co_primitives/library/
json.rs1use ipld_core::{ipld::Ipld, serde::to_ipld};
5use serde::{de::DeserializeOwned, Deserialize, Serialize};
6
7pub fn to_json<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
9 let ipld =
10 to_ipld(value).map_err(|err| JsonError::Serialize(std::any::type_name::<T>().to_owned(), err.to_string()))?;
11 serde_ipld_dagjson::to_vec(&ipld)
12 .map_err(|err| JsonError::Serialize(std::any::type_name::<T>().to_owned(), err.to_string()))
13}
14
15pub fn from_json<'a, T: Deserialize<'a>>(value: &'a [u8]) -> Result<T, JsonError> {
17 let ipld: Ipld = serde_ipld_dagjson::from_slice(value)
19 .map_err(|err| JsonError::Deserialize(std::any::type_name::<T>().to_owned(), err.to_string()))?;
20 T::deserialize(ipld).map_err(|err| JsonError::Deserialize(std::any::type_name::<T>().to_owned(), err.to_string()))
21}
22
23pub fn to_json_string<T: Serialize>(value: &T) -> Result<String, JsonError> {
25 String::from_utf8(to_json(value)?)
26 .map_err(|err| JsonError::Serialize(std::any::type_name::<T>().to_owned(), err.to_string()))
27}
28
29pub fn from_json_string<T: DeserializeOwned>(value: impl AsRef<[u8]>) -> Result<T, JsonError> {
31 from_json(value.as_ref())
32 .map_err(|err| JsonError::Deserialize(std::any::type_name::<T>().to_owned(), err.to_string()))
33}
34
35#[derive(Debug, thiserror::Error)]
36pub enum JsonError {
37 #[error("Serialize {0} to JSON failed: {1}")]
38 Serialize(String, String),
39
40 #[error("Deserialize {0} from JSON failed: {1}")]
41 Deserialize(String, String),
42}
43
44#[cfg(test)]
45mod tests {
46 use crate::{from_json, to_json};
47 use serde::{Deserialize, Serialize};
48
49 #[derive(Debug, Serialize, Deserialize, PartialEq)]
50 struct Test {
51 #[serde(with = "serde_bytes")]
52 hello: Vec<u8>,
53 }
54
55 #[test]
56 fn test_bytes() {
57 let payload = Test { hello: "world".as_bytes().to_vec() };
58 let json = to_json(&payload).unwrap();
59 assert_eq!(std::str::from_utf8(&json).unwrap(), "{\"hello\":{\"/\":{\"bytes\":\"d29ybGQ\"}}}");
60 let deserialized: Test = from_json(&json).unwrap();
61 assert_eq!(deserialized, payload);
62 }
63}