ipld_nostd/ipld/serde/
ser.rs

1// Parts of this code is based on
2// https://github.com/serde-rs/json/blob/95f67a09399d546d9ecadeb747a845a77ff309b2/src/value/ser.rs
3use {
4	super::super::{serde::SerdeError, Ipld},
5	crate::cid::{serde::CID_SERDE_PRIVATE_IDENTIFIER, Cid},
6	alloc::{
7		borrow::ToOwned,
8		collections::BTreeMap,
9		format,
10		string::{String, ToString},
11		vec::Vec,
12	},
13	core::convert::TryFrom,
14	serde::ser,
15};
16
17/// Serialize into instances of [`crate::ipld::Ipld`].
18///
19/// All Rust types can be serialized to [`crate::ipld::Ipld`], here is a list of
20/// how they are converted:
21///
22///  - bool -> `Ipld::Bool`
23///  - i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, usize ->
24///    `Ipld::Integer`
25///  - f32, f64 -> `Ipld::Float`
26///  - char, String -> `Ipld::String`
27///  - slices -> `Ipld::List`
28///  - struct
29///    - struct -> `Ipld::Map`
30///    - newtype struct -> the value the struct wraps
31///    - tuple struct -> `Ipld::List`
32///    - unit struct -> cannot be serialized, it errors
33///  - enum:
34///    - unit variant -> `Ipld::String` of the variant name
35///    - newtype variant -> single element `Ipld::Map`, key: variant name,
36///      value: the one the newtype wraps
37///    - tuple variant -> single element `Ipld::Map`, key: variant name, value:
38///      `Ipld::List`
39///    - struct variant -> single element `Ipld::Map`, key: variant name, value:
40///      `Ipld::Map`
41///  - unit (`()`) -> cannot be serialized, it errors
42///
43/// There are also common compound types that are supported:
44///
45///  - [`std::option::Option`] -> eithe `Ipld::Null` or the value
46///  - [`serde_bytes::ByteBuf`] -> `Ipld::Bytes`
47///  - lists (like e.g. [`std::vec::Vec`]) -> `Ipld::List`
48///  - maps (like e.g. [`std::collections::BTreeMap`]) -> `Ipld::Map`
49///  - [`cid::Cid`] -> `Ipld::Link`
50///
51///
52/// # Example
53///
54/// ```
55/// use {
56/// 	ipld_core::{ipld::Ipld, serde::to_ipld},
57/// 	serde_derive::Serialize,
58/// };
59///
60/// #[derive(Serialize)]
61/// struct Person {
62/// 	name: String,
63/// 	age: u8,
64/// 	hobbies: Vec<String>,
65/// 	is_cool: bool,
66/// }
67///
68/// let person = Person {
69/// 	name: "Hello World!".into(),
70/// 	age: 52,
71/// 	hobbies: vec!["geography".into(), "programming".into()],
72/// 	is_cool: true,
73/// };
74///
75/// let ipld = to_ipld(person);
76/// assert!(matches!(ipld, Ok(Ipld::Map(_))));
77/// ```
78pub fn to_ipld<T>(value: T) -> Result<Ipld, SerdeError>
79where
80	T: ser::Serialize,
81{
82	value.serialize(Serializer)
83}
84
85impl ser::Serialize for Ipld {
86	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
87	where
88		S: ser::Serializer,
89	{
90		match &self {
91			Self::Null => serializer.serialize_none(),
92			Self::Bool(value) => serializer.serialize_bool(*value),
93			Self::Integer(value) => serializer.serialize_i128(*value),
94			Self::Float(value) => serializer.serialize_f64(*value),
95			Self::String(value) => serializer.serialize_str(value),
96			Self::Bytes(value) => serializer.serialize_bytes(value),
97			Self::List(value) => serializer.collect_seq(value),
98			Self::Map(value) => serializer.collect_map(value),
99			Self::Link(value) => value.serialize(serializer),
100		}
101	}
102}
103
104/// The IPLD serializer.
105pub struct Serializer;
106
107impl serde::Serializer for Serializer {
108	type Error = SerdeError;
109	type Ok = Ipld;
110	type SerializeMap = SerializeMap;
111	type SerializeSeq = SerializeVec;
112	type SerializeStruct = SerializeMap;
113	type SerializeStructVariant = SerializeStructVariant;
114	type SerializeTuple = SerializeVec;
115	type SerializeTupleStruct = SerializeVec;
116	type SerializeTupleVariant = SerializeTupleVariant;
117
118	#[inline]
119	fn serialize_bool(self, value: bool) -> Result<Self::Ok, Self::Error> {
120		Ok(Self::Ok::Bool(value))
121	}
122
123	#[inline]
124	fn serialize_i8(self, value: i8) -> Result<Self::Ok, Self::Error> {
125		self.serialize_i64(i64::from(value))
126	}
127
128	#[inline]
129	fn serialize_i16(self, value: i16) -> Result<Self::Ok, Self::Error> {
130		self.serialize_i64(i64::from(value))
131	}
132
133	#[inline]
134	fn serialize_i32(self, value: i32) -> Result<Self::Ok, Self::Error> {
135		self.serialize_i64(i64::from(value))
136	}
137
138	#[inline]
139	fn serialize_i64(self, value: i64) -> Result<Self::Ok, Self::Error> {
140		self.serialize_i128(i128::from(value))
141	}
142
143	fn serialize_i128(self, value: i128) -> Result<Self::Ok, Self::Error> {
144		Ok(Self::Ok::Integer(value))
145	}
146
147	#[inline]
148	fn serialize_u8(self, value: u8) -> Result<Self::Ok, Self::Error> {
149		self.serialize_i128(value.into())
150	}
151
152	#[inline]
153	fn serialize_u16(self, value: u16) -> Result<Self::Ok, Self::Error> {
154		self.serialize_i128(value.into())
155	}
156
157	#[inline]
158	fn serialize_u32(self, value: u32) -> Result<Self::Ok, Self::Error> {
159		self.serialize_i128(value.into())
160	}
161
162	#[inline]
163	fn serialize_u64(self, value: u64) -> Result<Self::Ok, Self::Error> {
164		self.serialize_i128(value.into())
165	}
166
167	#[inline]
168	fn serialize_f32(self, value: f32) -> Result<Self::Ok, Self::Error> {
169		self.serialize_f64(f64::from(value))
170	}
171
172	#[inline]
173	fn serialize_f64(self, value: f64) -> Result<Self::Ok, Self::Error> {
174		Ok(Self::Ok::Float(value))
175	}
176
177	#[inline]
178	fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
179		self.serialize_str(&value.to_string())
180	}
181
182	#[inline]
183	fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
184		Ok(Self::Ok::String(value.to_owned()))
185	}
186
187	fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
188		Ok(Self::Ok::Bytes(value.to_vec()))
189	}
190
191	#[inline]
192	fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
193		Err(ser::Error::custom("Unit is not supported"))
194	}
195
196	#[inline]
197	fn serialize_unit_struct(
198		self,
199		_name: &'static str,
200	) -> Result<Self::Ok, Self::Error> {
201		Err(ser::Error::custom("Unit structs are not supported"))
202	}
203
204	#[inline]
205	fn serialize_unit_variant(
206		self,
207		_name: &'static str,
208		_variant_index: u32,
209		variant: &'static str,
210	) -> Result<Self::Ok, Self::Error> {
211		self.serialize_str(variant)
212	}
213
214	#[inline]
215	fn serialize_newtype_struct<T>(
216		self,
217		name: &'static str,
218		value: &T,
219	) -> Result<Self::Ok, Self::Error>
220	where
221		T: ser::Serialize + ?Sized,
222	{
223		let ipld = value.serialize(self);
224		if name == CID_SERDE_PRIVATE_IDENTIFIER {
225			if let Ok(Ipld::Bytes(bytes)) = ipld {
226				let cid = Cid::try_from(bytes)
227					.map_err(|err| ser::Error::custom(format!("Invalid CID: {}", err)))?;
228				return Ok(Self::Ok::Link(cid));
229			}
230		}
231		ipld
232	}
233
234	fn serialize_newtype_variant<T>(
235		self,
236		_name: &'static str,
237		_variant_index: u32,
238		variant: &'static str,
239		value: &T,
240	) -> Result<Self::Ok, Self::Error>
241	where
242		T: ser::Serialize + ?Sized,
243	{
244		let values = BTreeMap::from([(variant.to_owned(), value.serialize(self)?)]);
245		Ok(Self::Ok::Map(values))
246	}
247
248	#[inline]
249	fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
250		Ok(Self::Ok::Null)
251	}
252
253	#[inline]
254	fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
255	where
256		T: ser::Serialize + ?Sized,
257	{
258		value.serialize(self)
259	}
260
261	fn serialize_seq(
262		self,
263		len: Option<usize>,
264	) -> Result<Self::SerializeSeq, Self::Error> {
265		Ok(SerializeVec {
266			vec: Vec::with_capacity(len.unwrap_or(0)),
267		})
268	}
269
270	fn serialize_tuple(
271		self,
272		len: usize,
273	) -> Result<Self::SerializeTuple, Self::Error> {
274		self.serialize_seq(Some(len))
275	}
276
277	fn serialize_tuple_struct(
278		self,
279		_name: &'static str,
280		len: usize,
281	) -> Result<Self::SerializeTupleStruct, Self::Error> {
282		self.serialize_tuple(len)
283	}
284
285	fn serialize_tuple_variant(
286		self,
287		_name: &'static str,
288		_variant_index: u32,
289		variant: &'static str,
290		len: usize,
291	) -> Result<Self::SerializeTupleVariant, Self::Error> {
292		Ok(SerializeTupleVariant {
293			name: String::from(variant),
294			vec: Vec::with_capacity(len),
295		})
296	}
297
298	fn serialize_map(
299		self,
300		_len: Option<usize>,
301	) -> Result<Self::SerializeMap, Self::Error> {
302		Ok(SerializeMap {
303			map: BTreeMap::new(),
304			next_key: None,
305		})
306	}
307
308	fn serialize_struct(
309		self,
310		_name: &'static str,
311		len: usize,
312	) -> Result<Self::SerializeStruct, Self::Error> {
313		self.serialize_map(Some(len))
314	}
315
316	fn serialize_struct_variant(
317		self,
318		_name: &'static str,
319		_variant_index: u32,
320		variant: &'static str,
321		_len: usize,
322	) -> Result<Self::SerializeStructVariant, Self::Error> {
323		Ok(SerializeStructVariant {
324			name: String::from(variant),
325			map: BTreeMap::new(),
326		})
327	}
328
329	#[inline]
330	fn is_human_readable(&self) -> bool {
331		false
332	}
333}
334
335pub struct SerializeVec {
336	vec: Vec<Ipld>,
337}
338
339pub struct SerializeTupleVariant {
340	name: String,
341	vec: Vec<Ipld>,
342}
343
344pub struct SerializeMap {
345	map: BTreeMap<String, Ipld>,
346	next_key: Option<String>,
347}
348
349pub struct SerializeStructVariant {
350	name: String,
351	map: BTreeMap<String, Ipld>,
352}
353
354impl ser::SerializeSeq for SerializeVec {
355	type Error = SerdeError;
356	type Ok = Ipld;
357
358	fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
359	where
360		T: ser::Serialize + ?Sized,
361	{
362		self.vec.push(value.serialize(Serializer)?);
363		Ok(())
364	}
365
366	fn end(self) -> Result<Self::Ok, Self::Error> {
367		Ok(Self::Ok::List(self.vec))
368	}
369}
370
371impl ser::SerializeTuple for SerializeVec {
372	type Error = SerdeError;
373	type Ok = Ipld;
374
375	fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
376	where
377		T: ser::Serialize + ?Sized,
378	{
379		ser::SerializeSeq::serialize_element(self, value)
380	}
381
382	fn end(self) -> Result<Self::Ok, Self::Error> {
383		ser::SerializeSeq::end(self)
384	}
385}
386
387impl ser::SerializeTupleStruct for SerializeVec {
388	type Error = SerdeError;
389	type Ok = Ipld;
390
391	fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
392	where
393		T: ser::Serialize + ?Sized,
394	{
395		ser::SerializeSeq::serialize_element(self, value)
396	}
397
398	fn end(self) -> Result<Self::Ok, Self::Error> {
399		ser::SerializeSeq::end(self)
400	}
401}
402
403impl ser::SerializeTupleVariant for SerializeTupleVariant {
404	type Error = SerdeError;
405	type Ok = Ipld;
406
407	fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
408	where
409		T: ser::Serialize + ?Sized,
410	{
411		self.vec.push(value.serialize(Serializer)?);
412		Ok(())
413	}
414
415	fn end(self) -> Result<Self::Ok, Self::Error> {
416		let map = BTreeMap::from([(self.name, Self::Ok::List(self.vec))]);
417		Ok(Self::Ok::Map(map))
418	}
419}
420
421impl ser::SerializeMap for SerializeMap {
422	type Error = SerdeError;
423	type Ok = Ipld;
424
425	fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
426	where
427		T: ser::Serialize + ?Sized,
428	{
429		match key.serialize(Serializer)? {
430			Ipld::String(string_key) => {
431				self.next_key = Some(string_key);
432				Ok(())
433			}
434			_ => Err(ser::Error::custom("Map keys must be strings".to_string())),
435		}
436	}
437
438	fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
439	where
440		T: ser::Serialize + ?Sized,
441	{
442		let key = self.next_key.take();
443		// Panic because this indicates a bug in the program rather than an
444		// expected failure.
445		let key = key.expect("serialize_value called before serialize_key");
446		self.map.insert(key, value.serialize(Serializer)?);
447		Ok(())
448	}
449
450	fn end(self) -> Result<Self::Ok, Self::Error> {
451		Ok(Self::Ok::Map(self.map))
452	}
453}
454
455impl ser::SerializeStruct for SerializeMap {
456	type Error = SerdeError;
457	type Ok = Ipld;
458
459	fn serialize_field<T>(
460		&mut self,
461		key: &'static str,
462		value: &T,
463	) -> Result<(), Self::Error>
464	where
465		T: ser::Serialize + ?Sized,
466	{
467		serde::ser::SerializeMap::serialize_key(self, key)?;
468		serde::ser::SerializeMap::serialize_value(self, value)
469	}
470
471	fn end(self) -> Result<Self::Ok, Self::Error> {
472		serde::ser::SerializeMap::end(self)
473	}
474}
475
476impl ser::SerializeStructVariant for SerializeStructVariant {
477	type Error = SerdeError;
478	type Ok = Ipld;
479
480	fn serialize_field<T>(
481		&mut self,
482		key: &'static str,
483		value: &T,
484	) -> Result<(), Self::Error>
485	where
486		T: ser::Serialize + ?Sized,
487	{
488		self
489			.map
490			.insert(key.to_string(), value.serialize(Serializer)?);
491		Ok(())
492	}
493
494	fn end(self) -> Result<Self::Ok, Self::Error> {
495		let mut object = BTreeMap::new();
496
497		object.insert(self.name, Self::Ok::Map(self.map));
498
499		Ok(Self::Ok::Map(object))
500	}
501}