nym_serde_helpers/
lib.rs

1// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4#[cfg(feature = "base64")]
5pub mod base64 {
6    use base64::{Engine as _, engine::general_purpose::STANDARD};
7    use serde::{Deserialize, Deserializer, Serializer};
8
9    pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
10        serializer.serialize_str(&STANDARD.encode(bytes))
11    }
12
13    pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
14        let s = <String>::deserialize(deserializer)?;
15        STANDARD.decode(s).map_err(serde::de::Error::custom)
16    }
17}
18
19#[cfg(feature = "bs58")]
20pub mod bs58 {
21    use serde::{Deserialize, Deserializer, Serializer};
22
23    pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
24        serializer.serialize_str(&::bs58::encode(bytes).into_string())
25    }
26
27    pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
28        let s = String::deserialize(deserializer)?;
29        ::bs58::decode(&s)
30            .into_vec()
31            .map_err(serde::de::Error::custom)
32    }
33}
34
35#[cfg(feature = "hex")]
36pub mod hex {
37    use serde::{Deserialize, Deserializer, Serializer};
38
39    pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
40        serializer.serialize_str(&::hex::encode(bytes))
41    }
42
43    pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
44        let s = String::deserialize(deserializer)?;
45        ::hex::decode(&s).map_err(serde::de::Error::custom)
46    }
47}
48
49#[cfg(feature = "date")]
50pub mod date {
51    use serde::ser::Error;
52    use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
53    use time::Date;
54    use time::format_description::{BorrowedFormatItem, Component, modifier};
55
56    // simple YYYY-MM-DD
57    pub const DATE_FORMAT: &[BorrowedFormatItem<'_>] = &[
58        BorrowedFormatItem::Component(Component::Year(modifier::Year::default())),
59        BorrowedFormatItem::Literal(b"-"),
60        BorrowedFormatItem::Component(Component::Month(modifier::Month::default())),
61        BorrowedFormatItem::Literal(b"-"),
62        BorrowedFormatItem::Component(Component::Day(modifier::Day::default())),
63    ];
64
65    pub fn deserialize<'de, D>(deserializer: D) -> Result<Date, D::Error>
66    where
67        D: Deserializer<'de>,
68    {
69        let s = String::deserialize(deserializer)?;
70
71        Date::parse(&s, DATE_FORMAT).map_err(de::Error::custom)
72    }
73
74    pub fn serialize<S>(datetime: &Date, serializer: S) -> Result<S::Ok, S::Error>
75    where
76        S: Serializer,
77    {
78        // serialize it with human-readable format for compatibility with eclipse and nutella clients
79        // in the future change it back to rfc3339
80        datetime
81            .format(&DATE_FORMAT)
82            .map_err(S::Error::custom)?
83            .serialize(serializer)
84    }
85}