defuse_borsh_utils/
duration.rs1use core::{fmt::Display, marker::PhantomData, time::Duration};
2
3use borsh::{BorshDeserialize, BorshSerialize, io};
4
5use crate::{BorshDeserializeAs, BorshSerializeAs};
6
7pub struct DurationSeconds<I = u64>(PhantomData<I>);
8
9impl<I> BorshSerializeAs<Duration> for DurationSeconds<I>
10where
11 I: TryFrom<u64> + BorshSerialize,
12 I::Error: Display,
13{
14 fn serialize_as<W>(source: &Duration, writer: &mut W) -> io::Result<()>
15 where
16 W: io::Write,
17 {
18 I::try_from(source.as_secs())
19 .map_err(|err| io::Error::other(err.to_string()))?
20 .serialize(writer)
21 }
22}
23
24impl<I> BorshDeserializeAs<Duration> for DurationSeconds<I>
25where
26 I: TryInto<u64> + BorshDeserialize,
27 I::Error: Display,
28{
29 fn deserialize_as<R>(reader: &mut R) -> io::Result<Duration>
30 where
31 R: io::Read,
32 {
33 I::deserialize_reader(reader)?
34 .try_into()
35 .map(Duration::from_secs)
36 .map_err(|err| io::Error::other(err.to_string()))
37 }
38}
39
40pub struct DurationMilliSeconds<I = u64>(PhantomData<I>);
41
42impl<I> BorshSerializeAs<Duration> for DurationMilliSeconds<I>
43where
44 I: TryFrom<u128> + BorshSerialize,
45 I::Error: Display,
46{
47 fn serialize_as<W>(source: &Duration, writer: &mut W) -> io::Result<()>
48 where
49 W: io::Write,
50 {
51 I::try_from(source.as_millis())
52 .map_err(|err| io::Error::other(err.to_string()))?
53 .serialize(writer)
54 }
55}
56
57impl<I> BorshDeserializeAs<Duration> for DurationMilliSeconds<I>
58where
59 I: TryInto<u64> + BorshDeserialize,
60 I::Error: Display,
61{
62 fn deserialize_as<R>(reader: &mut R) -> io::Result<Duration>
63 where
64 R: io::Read,
65 {
66 I::deserialize_reader(reader)?
67 .try_into()
68 .map(Duration::from_millis)
69 .map_err(|err| io::Error::other(err.to_string()))
70 }
71}
72
73pub struct DurationMicroSeconds<I = u64>(PhantomData<I>);
74
75impl<I> BorshSerializeAs<Duration> for DurationMicroSeconds<I>
76where
77 I: TryFrom<u128> + BorshSerialize,
78 I::Error: Display,
79{
80 fn serialize_as<W>(source: &Duration, writer: &mut W) -> io::Result<()>
81 where
82 W: io::Write,
83 {
84 I::try_from(source.as_micros())
85 .map_err(|err| io::Error::other(err.to_string()))?
86 .serialize(writer)
87 }
88}
89
90impl<I> BorshDeserializeAs<Duration> for DurationMicroSeconds<I>
91where
92 I: TryInto<u64> + BorshDeserialize,
93 I::Error: Display,
94{
95 fn deserialize_as<R>(reader: &mut R) -> io::Result<Duration>
96 where
97 R: io::Read,
98 {
99 I::deserialize_reader(reader)?
100 .try_into()
101 .map(Duration::from_micros)
102 .map_err(|err| io::Error::other(err.to_string()))
103 }
104}
105
106pub struct DurationNanoSeconds<I = u64>(PhantomData<I>);
107
108impl<I> BorshSerializeAs<Duration> for DurationNanoSeconds<I>
109where
110 I: TryFrom<u128> + BorshSerialize,
111 I::Error: Display,
112{
113 fn serialize_as<W>(source: &Duration, writer: &mut W) -> io::Result<()>
114 where
115 W: io::Write,
116 {
117 I::try_from(source.as_nanos())
118 .map_err(|err| io::Error::other(err.to_string()))?
119 .serialize(writer)
120 }
121}
122
123impl<I> BorshDeserializeAs<Duration> for DurationNanoSeconds<I>
124where
125 I: TryInto<u64> + BorshDeserialize,
126 I::Error: Display,
127{
128 fn deserialize_as<R>(reader: &mut R) -> io::Result<Duration>
129 where
130 R: io::Read,
131 {
132 I::deserialize_reader(reader)?
133 .try_into()
134 .map(Duration::from_nanos)
135 .map_err(|err| io::Error::other(err.to_string()))
136 }
137}
138
139#[cfg(feature = "schema")]
140const _: () = {
141 use crate::schema::impl_borsh_schema_as;
142
143 impl_borsh_schema_as!(Duration, DurationSeconds);
144 impl_borsh_schema_as!(Duration, DurationMilliSeconds);
145 impl_borsh_schema_as!(Duration, DurationMicroSeconds);
146 impl_borsh_schema_as!(Duration, DurationNanoSeconds);
147};