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