server/
rkyv_with.rs

1// SPDX-FileCopyrightText: 2025 Foundation Devices, Inc. <hello@foundation.xyz>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4//! Custom rkyv serialization helpers for KeyOS
5
6use std::time::{Duration, SystemTime, UNIX_EPOCH};
7
8use rkyv::{
9    with::{ArchiveWith, DeserializeWith, SerializeWith},
10    Archive, Archived, Deserialize, Place, Serialize,
11};
12
13/// A custom UnixTimestamp implementation that doesn't have an error.
14/// making it compatible with infallible error types
15pub struct WithUnixTimestamp;
16
17impl ArchiveWith<SystemTime> for WithUnixTimestamp {
18    type Archived = Archived<Duration>;
19    type Resolver = <Duration as Archive>::Resolver;
20
21    #[inline]
22    fn resolve_with(field: &SystemTime, resolver: Self::Resolver, out: Place<Self::Archived>) {
23        let duration = field.duration_since(UNIX_EPOCH).unwrap_or_default();
24        Archive::resolve(&duration, resolver, out);
25    }
26}
27
28impl<S> SerializeWith<SystemTime, S> for WithUnixTimestamp
29where
30    S: rkyv::rancor::Fallible + ?Sized,
31{
32    fn serialize_with(field: &SystemTime, s: &mut S) -> Result<Self::Resolver, S::Error> {
33        let duration = field.duration_since(UNIX_EPOCH).unwrap_or_default();
34        duration.serialize(s)
35    }
36}
37
38impl<D> DeserializeWith<Archived<Duration>, SystemTime, D> for WithUnixTimestamp
39where
40    D: rkyv::rancor::Fallible + ?Sized,
41{
42    fn deserialize_with(field: &Archived<Duration>, _: &mut D) -> Result<SystemTime, D::Error> {
43        Ok(UNIX_EPOCH + Duration::from(*field))
44    }
45}
46
47pub struct WithAppId;
48
49impl ArchiveWith<xous::AppId> for WithAppId {
50    type Archived = Archived<[u32; 4]>;
51    type Resolver = <[u32; 4] as Archive>::Resolver;
52
53    #[inline]
54    fn resolve_with(field: &xous::AppId, resolver: Self::Resolver, out: Place<Self::Archived>) {
55        let words: [u32; 4] = field.into();
56        Archive::resolve(&words, resolver, out);
57    }
58}
59
60impl<S> SerializeWith<xous::AppId, S> for WithAppId
61where
62    S: rkyv::rancor::Fallible + ?Sized,
63{
64    fn serialize_with(field: &xous::AppId, s: &mut S) -> Result<Self::Resolver, S::Error> {
65        let words: [u32; 4] = field.into();
66        words.serialize(s)
67    }
68}
69
70impl<D> DeserializeWith<Archived<[u32; 4]>, xous::AppId, D> for WithAppId
71where
72    D: rkyv::rancor::Fallible + ?Sized,
73{
74    fn deserialize_with(field: &Archived<[u32; 4]>, d: &mut D) -> Result<xous::AppId, D::Error> {
75        let words = field.deserialize(d)?;
76        Ok(words.into())
77    }
78}