r402_protocol/payment/
codec.rs1use std::fmt::{self, Display, Formatter};
4use std::ops::Add;
5use std::str::FromStr;
6use std::time::SystemTime;
7
8use base64::Engine;
9use base64::engine::general_purpose::STANDARD as B64;
10use serde::{Deserialize, Deserializer, Serialize, Serializer};
11use serde_with::{DisplayFromStr, serde_as};
12
13#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)]
15pub struct Version<const N: u8>;
16
17impl<const N: u8> Version<N> {
18 pub const VALUE: u8 = N;
20}
21
22impl<const N: u8> PartialEq<u8> for Version<N> {
23 fn eq(&self, other: &u8) -> bool {
24 *other == N
25 }
26}
27
28impl<const N: u8> From<Version<N>> for u8 {
29 fn from(_: Version<N>) -> Self {
30 N
31 }
32}
33
34impl<const N: u8> Display for Version<N> {
35 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
36 write!(f, "{N}")
37 }
38}
39
40impl<const N: u8> Serialize for Version<N> {
41 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
42 serializer.serialize_u8(N)
43 }
44}
45
46impl<'de, const N: u8> Deserialize<'de> for Version<N> {
47 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
48 let v = u8::deserialize(deserializer)?;
49 if v == N {
50 Ok(Self)
51 } else {
52 Err(serde::de::Error::custom(format!(
53 "expected protocol version {N}, got {v}"
54 )))
55 }
56 }
57}
58
59pub type Version2 = Version<2>;
61
62pub const V2: Version2 = Version;
64
65#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct Base64Bytes(pub Vec<u8>);
79
80impl Base64Bytes {
81 pub fn decode(&self) -> Result<Vec<u8>, base64::DecodeError> {
88 B64.decode(&self.0)
89 }
90
91 #[must_use]
93 pub fn encode<T: AsRef<[u8]>>(input: T) -> Self {
94 Self(B64.encode(input.as_ref()).into_bytes())
95 }
96}
97
98impl AsRef<[u8]> for Base64Bytes {
99 fn as_ref(&self) -> &[u8] {
100 &self.0
101 }
102}
103
104impl From<&[u8]> for Base64Bytes {
105 fn from(slice: &[u8]) -> Self {
106 Self(slice.to_vec())
107 }
108}
109
110impl Display for Base64Bytes {
111 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
112 f.write_str(&String::from_utf8_lossy(&self.0))
113 }
114}
115
116#[serde_as]
128#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
129#[repr(transparent)]
130pub struct U64String(#[serde_as(as = "DisplayFromStr")] u64);
131
132impl U64String {
133 #[must_use]
135 pub const fn inner(self) -> u64 {
136 self.0
137 }
138}
139
140impl Display for U64String {
141 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
142 Display::fmt(&self.0, f)
143 }
144}
145
146impl FromStr for U64String {
147 type Err = <u64 as FromStr>::Err;
148 fn from_str(s: &str) -> Result<Self, Self::Err> {
149 s.parse::<u64>().map(Self)
150 }
151}
152
153impl From<u64> for U64String {
154 fn from(value: u64) -> Self {
155 Self(value)
156 }
157}
158
159impl From<U64String> for u64 {
160 fn from(value: U64String) -> Self {
161 value.0
162 }
163}
164
165#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)]
180pub struct UnixTimestamp(u64);
181
182impl UnixTimestamp {
183 #[must_use]
185 pub const fn from_secs(secs: u64) -> Self {
186 Self(secs)
187 }
188
189 #[must_use]
193 pub fn now() -> Self {
194 let secs = SystemTime::now()
195 .duration_since(SystemTime::UNIX_EPOCH)
196 .map(|d| d.as_secs())
197 .unwrap_or_default();
198 Self(secs)
199 }
200
201 #[must_use]
203 pub const fn as_secs(self) -> u64 {
204 self.0
205 }
206}
207
208impl Display for UnixTimestamp {
209 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
210 Display::fmt(&self.0, f)
211 }
212}
213
214impl Add<u64> for UnixTimestamp {
215 type Output = Self;
216 fn add(self, rhs: u64) -> Self::Output {
217 Self(self.0.saturating_add(rhs))
218 }
219}
220
221impl Serialize for UnixTimestamp {
222 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
223 serializer.collect_str(&self.0)
224 }
225}
226
227impl<'de> Deserialize<'de> for UnixTimestamp {
228 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
229 struct Visitor;
230
231 impl serde::de::Visitor<'_> for Visitor {
232 type Value = UnixTimestamp;
233
234 fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result {
235 f.write_str("a non-negative integer or its string representation")
236 }
237
238 fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Self::Value, E> {
239 Ok(UnixTimestamp(v))
240 }
241
242 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
243 v.parse::<u64>()
244 .map(UnixTimestamp)
245 .map_err(|_| E::custom("expected non-negative integer"))
246 }
247 }
248
249 deserializer.deserialize_any(Visitor)
250 }
251}