secret_cosmwasm_std/
serde.rs

1// This file simply re-exports some methods from serde_json
2// The reason is two fold:
3// 1. To easily ensure that all calling libraries use the same version (minimize code size)
4// 2. To allow us to switch out to eg. serde-json-core more easily
5use serde::{de::DeserializeOwned, Serialize};
6use std::any::type_name;
7
8use crate::binary::Binary;
9use crate::errors::{StdError, StdResult};
10
11pub fn from_slice<T: DeserializeOwned>(value: &[u8]) -> StdResult<T> {
12    serde_json_wasm::from_slice(value).map_err(|e| StdError::parse_err(type_name::<T>(), e))
13}
14
15pub fn from_binary<T: DeserializeOwned>(value: &Binary) -> StdResult<T> {
16    from_slice(value.as_slice())
17}
18
19pub fn to_vec<T>(data: &T) -> StdResult<Vec<u8>>
20where
21    T: Serialize + ?Sized,
22{
23    serde_json_wasm::to_vec(data).map_err(|e| StdError::serialize_err(type_name::<T>(), e))
24}
25
26pub fn to_binary<T>(data: &T) -> StdResult<Binary>
27where
28    T: Serialize + ?Sized,
29{
30    to_vec(data).map(Binary)
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36    use serde::Deserialize;
37
38    #[derive(Serialize, Deserialize, Debug, PartialEq)]
39    #[serde(rename_all = "snake_case")]
40    enum SomeMsg {
41        Refund {},
42        ReleaseAll {
43            image: String,
44            amount: u32,
45            time: u64,
46            karma: i32,
47        },
48        Cowsay {
49            text: String,
50        },
51    }
52
53    #[test]
54    fn to_vec_works() {
55        let msg = SomeMsg::Refund {};
56        let serialized = to_vec(&msg).unwrap();
57        assert_eq!(serialized, br#"{"refund":{}}"#);
58
59        let msg = SomeMsg::ReleaseAll {
60            image: "foo".to_string(),
61            amount: 42,
62            time: 9007199254740999, // Number.MAX_SAFE_INTEGER + 7
63            karma: -17,
64        };
65        let serialized = String::from_utf8(to_vec(&msg).unwrap()).unwrap();
66        assert_eq!(
67            serialized,
68            r#"{"release_all":{"image":"foo","amount":42,"time":9007199254740999,"karma":-17}}"#
69        );
70    }
71
72    #[test]
73    fn from_slice_works() {
74        let deserialized: SomeMsg = from_slice(br#"{"refund":{}}"#).unwrap();
75        assert_eq!(deserialized, SomeMsg::Refund {});
76
77        let deserialized: SomeMsg = from_slice(
78            br#"{"release_all":{"image":"foo","amount":42,"time":18446744073709551615,"karma":-17}}"#,
79        )
80        .unwrap();
81        assert_eq!(
82            deserialized,
83            SomeMsg::ReleaseAll {
84                image: "foo".to_string(),
85                amount: 42,
86                time: 18446744073709551615,
87                karma: -17
88            }
89        );
90    }
91
92    #[test]
93    fn from_slice_or_binary() {
94        let msg = SomeMsg::Refund {};
95        let serialized: Binary = to_binary(&msg).unwrap();
96
97        let parse_binary: SomeMsg = from_binary(&serialized).unwrap();
98        assert_eq!(parse_binary, msg);
99
100        let parse_slice: SomeMsg = from_slice(&serialized).unwrap();
101        assert_eq!(parse_slice, msg);
102    }
103
104    #[test]
105    fn to_vec_works_for_special_chars() {
106        let msg = SomeMsg::Cowsay {
107            text: "foo\"bar\\\"bla".to_string(),
108        };
109        let serialized = String::from_utf8(to_vec(&msg).unwrap()).unwrap();
110        assert_eq!(serialized, r#"{"cowsay":{"text":"foo\"bar\\\"bla"}}"#);
111    }
112
113    #[test]
114    fn from_slice_works_for_special_chars() {
115        let deserialized: SomeMsg =
116            from_slice(br#"{"cowsay":{"text":"foo\"bar\\\"bla"}}"#).unwrap();
117        assert_eq!(
118            deserialized,
119            SomeMsg::Cowsay {
120                text: "foo\"bar\\\"bla".to_string(),
121            }
122        );
123    }
124}