platform_value/value_serialization/
mod.rs1use crate::value_serialization::ser::Serializer;
2use crate::{Error, Value};
3use serde::Deserialize;
4use serde::Serialize;
5
6pub mod de;
7pub mod ser;
8
9pub fn to_value<T>(value: T) -> Result<Value, Error>
62where
63 T: Serialize,
64{
65 value.serialize(Serializer)
66}
67
68pub fn from_value<'de, T>(value: Value) -> Result<T, Error>
102where
103 T: Deserialize<'de>,
104{
105 T::deserialize(de::Deserializer(value))
106}
107
108#[cfg(test)]
109#[allow(clippy::needless_borrows_for_generic_args)]
110mod tests {
111 use serde::{Deserialize, Serialize};
112 use std::collections::HashMap;
113
114 use super::*;
115
116 #[test]
117 fn yeet() {
118 #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
119 struct Yeet {
120 arr: Vec<String>,
121 map: HashMap<String, char>,
122 number: i32,
123 }
126
127 let mut hm = HashMap::new();
128 hm.insert("wow".to_owned(), 'a');
129 hm.insert("lol".to_owned(), 'd');
130
131 let yeet = Yeet {
132 arr: vec!["kek".to_owned(), "top".to_owned()],
133 map: hm,
134 number: 420,
135 };
137
138 let platform_value = to_value(yeet.clone()).expect("please");
139 let yeet_back: Yeet = from_value(platform_value).expect("please once again");
140
141 assert_eq!(yeet, yeet_back);
142 }
143
144 #[test]
145 fn test_externally_tagged_unit_variant() {
146 #[derive(Serialize, Deserialize, Debug, PartialEq)]
147 #[serde(rename_all = "camelCase")]
148 enum Choice {
149 Abstain,
150 Lock,
151 TowardsIdentity(String),
152 }
153
154 let v = to_value(&Choice::Abstain).unwrap();
155 assert_eq!(v, Value::Text("abstain".to_string()));
156 let back: Choice = from_value(v).unwrap();
157 assert_eq!(back, Choice::Abstain);
158
159 let v = to_value(&Choice::Lock).unwrap();
160 assert_eq!(v, Value::Text("lock".to_string()));
161 let back: Choice = from_value(v).unwrap();
162 assert_eq!(back, Choice::Lock);
163 }
164
165 #[test]
166 fn test_externally_tagged_newtype_variant() {
167 #[derive(Serialize, Deserialize, Debug, PartialEq)]
168 #[serde(rename_all = "camelCase")]
169 enum Choice {
170 Abstain,
171 Lock,
172 TowardsIdentity(String),
173 }
174
175 let v = to_value(&Choice::TowardsIdentity("abc".into())).unwrap();
176 let back: Choice = from_value(v).unwrap();
177 assert_eq!(back, Choice::TowardsIdentity("abc".into()));
178 }
179
180 #[test]
181 fn test_internally_tagged_enum() {
182 #[derive(Serialize, Deserialize, Debug, PartialEq)]
183 #[serde(tag = "$formatVersion")]
184 enum Info {
185 #[serde(rename = "0")]
186 V0 { name: String },
187 }
188
189 let v = to_value(&Info::V0 {
190 name: "test".into(),
191 })
192 .unwrap();
193 let back: Info = from_value(v).unwrap();
194 assert_eq!(
195 back,
196 Info::V0 {
197 name: "test".into()
198 }
199 );
200 }
201
202 #[test]
203 fn test_externally_tagged_struct_variant() {
204 #[derive(Serialize, Deserialize, Debug, PartialEq)]
205 enum Shape {
206 Circle { radius: f64 },
207 Rectangle { width: f64, height: f64 },
208 }
209
210 let v = to_value(&Shape::Circle { radius: 5.0 }).unwrap();
211 let back: Shape = from_value(v).unwrap();
212 assert_eq!(back, Shape::Circle { radius: 5.0 });
213
214 let v = to_value(&Shape::Rectangle {
215 width: 3.0,
216 height: 4.0,
217 })
218 .unwrap();
219 let back: Shape = from_value(v).unwrap();
220 assert_eq!(
221 back,
222 Shape::Rectangle {
223 width: 3.0,
224 height: 4.0
225 }
226 );
227 }
228
229 #[test]
230 fn test_externally_tagged_tuple_variant() {
231 #[derive(Serialize, Deserialize, Debug, PartialEq)]
232 enum Point {
233 TwoD(f64, f64),
234 ThreeD(f64, f64, f64),
235 }
236
237 let v = to_value(&Point::TwoD(1.0, 2.0)).unwrap();
238 let back: Point = from_value(v).unwrap();
239 assert_eq!(back, Point::TwoD(1.0, 2.0));
240
241 let v = to_value(&Point::ThreeD(1.0, 2.0, 3.0)).unwrap();
242 let back: Point = from_value(v).unwrap();
243 assert_eq!(back, Point::ThreeD(1.0, 2.0, 3.0));
244 }
245
246 #[test]
247 fn test_externally_tagged_newtype_wrapping_struct() {
248 #[derive(Serialize, Deserialize, Debug, PartialEq)]
249 #[serde(rename_all = "camelCase")]
250 enum Vote {
251 ResourceVote(InnerVote),
252 }
253
254 #[derive(Serialize, Deserialize, Debug, PartialEq)]
255 #[serde(rename_all = "camelCase")]
256 struct InnerVote {
257 poll_name: String,
258 choice: u32,
259 }
260
261 let v = to_value(&Vote::ResourceVote(InnerVote {
262 poll_name: "test".into(),
263 choice: 42,
264 }))
265 .unwrap();
266 let back: Vote = from_value(v).unwrap();
267 assert_eq!(
268 back,
269 Vote::ResourceVote(InnerVote {
270 poll_name: "test".into(),
271 choice: 42,
272 })
273 );
274 }
275}