1#[cfg(feature = "rkyv")]
2use rkyv::{
3 Archive, Archived, Deserialize, Place, Serialize,
4 rancor::Fallible,
5 with::{ArchiveWith, DeserializeWith, SerializeWith},
6};
7use std::path::PathBuf;
8
9use crate::chrono::{DateTime, Utc};
10
11#[derive(Debug, Clone, Copy, Default)]
13pub struct PathBufWrapper;
14
15impl ArchiveWith<PathBuf> for PathBufWrapper {
16 type Archived = Archived<String>;
17 type Resolver = <String as Archive>::Resolver;
18
19 fn resolve_with(
20 field: &PathBuf,
21 resolver: Self::Resolver,
22 out: Place<Self::Archived>,
23 ) {
24 let path_str = field.to_string_lossy().to_string();
25 path_str.resolve(resolver, out);
26 }
27}
28
29impl<S: Fallible + ?Sized> SerializeWith<PathBuf, S> for PathBufWrapper
30where
31 String: Serialize<S>,
32{
33 fn serialize_with(
34 field: &PathBuf,
35 serializer: &mut S,
36 ) -> Result<Self::Resolver, S::Error> {
37 let path_str = field.to_string_lossy().to_string();
38 path_str.serialize(serializer)
39 }
40}
41
42impl<D: Fallible + ?Sized> DeserializeWith<Archived<String>, PathBuf, D>
43 for PathBufWrapper
44where
45 Archived<String>: Deserialize<String, D>,
46{
47 fn deserialize_with(
48 field: &Archived<String>,
49 deserializer: &mut D,
50 ) -> Result<PathBuf, D::Error> {
51 let path_str: String = field.deserialize(deserializer)?;
52 Ok(PathBuf::from(path_str))
53 }
54}
55
56#[derive(Debug, Clone, Copy, Default)]
58pub struct DateTimeWrapper;
59
60impl ArchiveWith<DateTime<Utc>> for DateTimeWrapper {
61 type Archived = Archived<i64>; type Resolver = <i64 as Archive>::Resolver;
63
64 fn resolve_with(
65 field: &DateTime<Utc>,
66 resolver: Self::Resolver,
67 out: Place<Self::Archived>,
68 ) {
69 let timestamp = field.timestamp();
70 timestamp.resolve(resolver, out);
71 }
72}
73
74impl<S: Fallible + ?Sized> SerializeWith<DateTime<Utc>, S> for DateTimeWrapper
75where
76 i64: Serialize<S>,
77{
78 fn serialize_with(
79 field: &DateTime<Utc>,
80 serializer: &mut S,
81 ) -> Result<Self::Resolver, <S as Fallible>::Error> {
82 let timestamp = field.timestamp();
83 timestamp.serialize(serializer)
84 }
85}
86
87impl<D: Fallible + ?Sized> DeserializeWith<Archived<i64>, DateTime<Utc>, D>
88 for DateTimeWrapper
89where
90 Archived<i64>: Deserialize<i64, D>,
91{
92 fn deserialize_with(
93 field: &Archived<i64>,
94 deserializer: &mut D,
95 ) -> Result<DateTime<Utc>, <D as Fallible>::Error> {
96 let timestamp: i64 = field.deserialize(deserializer)?;
97 Ok(DateTime::from_timestamp(timestamp, 0).unwrap_or_else(Utc::now))
98 }
99}
100
101#[derive(Debug, Clone, Copy, Default)]
103pub struct VecPathBuf;
104
105impl ArchiveWith<Vec<PathBuf>> for VecPathBuf {
106 type Archived = Archived<Vec<String>>;
107 type Resolver = <Vec<String> as Archive>::Resolver;
108
109 fn resolve_with(
110 field: &Vec<PathBuf>,
111 resolver: Self::Resolver,
112 out: Place<Self::Archived>,
113 ) {
114 let strings: Vec<String> = field
115 .iter()
116 .map(|p| p.to_string_lossy().to_string())
117 .collect();
118 strings.resolve(resolver, out);
119 }
120}
121
122impl<S: Fallible + ?Sized> SerializeWith<Vec<PathBuf>, S> for VecPathBuf
123where
124 Vec<String>: Serialize<S>,
125{
126 fn serialize_with(
127 field: &Vec<PathBuf>,
128 serializer: &mut S,
129 ) -> Result<Self::Resolver, <S as Fallible>::Error> {
130 let strings: Vec<String> = field
131 .iter()
132 .map(|p| p.to_string_lossy().to_string())
133 .collect();
134 strings.serialize(serializer)
135 }
136}
137
138impl<D: Fallible + ?Sized>
139 DeserializeWith<Archived<Vec<String>>, Vec<PathBuf>, D> for VecPathBuf
140where
141 Archived<Vec<String>>: Deserialize<Vec<String>, D>,
142{
143 fn deserialize_with(
144 field: &Archived<Vec<String>>,
145 deserializer: &mut D,
146 ) -> Result<Vec<PathBuf>, <D as Fallible>::Error> {
147 let strings: Vec<String> = field.deserialize(deserializer)?;
148 Ok(strings.into_iter().map(PathBuf::from).collect())
149 }
150}
151
152#[derive(Debug, Clone, Copy, Default)]
154pub struct OptionDateTime;
155
156impl ArchiveWith<Option<DateTime<Utc>>> for OptionDateTime {
157 type Archived = Archived<Option<i64>>;
158 type Resolver = <Option<i64> as Archive>::Resolver;
159
160 fn resolve_with(
161 field: &Option<DateTime<Utc>>,
162 resolver: Self::Resolver,
163 out: Place<Self::Archived>,
164 ) {
165 let timestamp = field.map(|dt| dt.timestamp());
166 timestamp.resolve(resolver, out);
167 }
168}
169
170impl<S: Fallible + ?Sized> SerializeWith<Option<DateTime<Utc>>, S>
171 for OptionDateTime
172where
173 Option<i64>: Serialize<S>,
174{
175 fn serialize_with(
176 field: &Option<DateTime<Utc>>,
177 serializer: &mut S,
178 ) -> Result<Self::Resolver, <S as Fallible>::Error> {
179 let timestamp = field.map(|dt| dt.timestamp());
180 timestamp.serialize(serializer)
181 }
182}
183
184impl<D: Fallible + ?Sized>
185 DeserializeWith<Archived<Option<i64>>, Option<DateTime<Utc>>, D>
186 for OptionDateTime
187where
188 Archived<Option<i64>>: Deserialize<Option<i64>, D>,
189{
190 fn deserialize_with(
191 field: &Archived<Option<i64>>,
192 deserializer: &mut D,
193 ) -> Result<Option<DateTime<Utc>>, <D as Fallible>::Error> {
194 let timestamp: Option<i64> = field.deserialize(deserializer)?;
195 Ok(timestamp.and_then(|ts| DateTime::from_timestamp(ts, 0)))
196 }
197}
198
199#[derive(Debug, Clone, Copy, Default)]
201pub struct DurationWrapper;
202
203impl ArchiveWith<std::time::Duration> for DurationWrapper {
204 type Archived = Archived<u64>; type Resolver = <u64 as Archive>::Resolver;
206
207 fn resolve_with(
208 field: &std::time::Duration,
209 resolver: Self::Resolver,
210 out: Place<Self::Archived>,
211 ) {
212 let secs = field.as_secs();
213 secs.resolve(resolver, out);
214 }
215}
216
217impl<S: Fallible + ?Sized> SerializeWith<std::time::Duration, S>
218 for DurationWrapper
219where
220 u64: Serialize<S>,
221{
222 fn serialize_with(
223 field: &std::time::Duration,
224 serializer: &mut S,
225 ) -> Result<Self::Resolver, <S as Fallible>::Error> {
226 let secs = field.as_secs();
227 secs.serialize(serializer)
228 }
229}
230
231impl<D: Fallible + ?Sized>
232 DeserializeWith<Archived<u64>, std::time::Duration, D> for DurationWrapper
233where
234 Archived<u64>: Deserialize<u64, D>,
235{
236 fn deserialize_with(
237 field: &Archived<u64>,
238 deserializer: &mut D,
239 ) -> Result<std::time::Duration, <D as Fallible>::Error> {
240 let secs: u64 = field.deserialize(deserializer)?;
241 Ok(std::time::Duration::from_secs(secs))
242 }
243}