serde_brief/
ser.rs

1//! Serialization implementation.
2#![cfg_attr(
3	feature = "tracing",
4	allow(clippy::used_underscore_binding, reason = "Only used in tracing::instrument")
5)]
6
7use ::serde::Serialize;
8
9use crate::{
10	format::{Type, VarInt},
11	io::Output,
12	Config, Error,
13};
14
15/// The serializer for the binary format.
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct Serializer<O> {
18	/// The output to write to.
19	output: O,
20	/// Serialize enum variants and struct fields by index instead of name-string.
21	use_indices: bool,
22}
23
24impl<O> Serializer<O> {
25	/// Create a new serializer from any [Output] compatible type.
26	#[must_use]
27	pub fn new(output: O) -> Self
28	where
29		// Same bounds as `serde::Serializer` impl.
30		O: Output,
31	{
32		Self { output, use_indices: Config::default().use_indices }
33	}
34
35	/// Set whether to use indices instead of names for enum variants and struct fields.
36	#[must_use]
37	pub const fn use_indices(mut self, use_indices: bool) -> Self {
38		self.use_indices = use_indices;
39		self
40	}
41
42	/// Consume the serializer to get the output back.
43	#[inline]
44	pub fn into_output(self) -> O {
45		self.output
46	}
47}
48
49impl<'a, O> ::serde::Serializer for &'a mut Serializer<O>
50where
51	O: Output,
52{
53	type Ok = ();
54	type Error = Error;
55
56	type SerializeSeq = Self;
57	type SerializeTuple = Self;
58	type SerializeTupleStruct = Self;
59	type SerializeTupleVariant = Self;
60	type SerializeMap = Self;
61	type SerializeStruct = StructSerializer<'a, O>;
62	type SerializeStructVariant = StructSerializer<'a, O>;
63
64	#[inline]
65	fn is_human_readable(&self) -> bool {
66		false
67	}
68
69	#[inline]
70	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
71	fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
72		if v {
73			self.output.write_byte(Type::BooleanTrue.into())?;
74		} else {
75			self.output.write_byte(Type::BooleanFalse.into())?;
76		}
77		Ok(())
78	}
79
80	#[inline]
81	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
82	fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
83		self.output.write_byte(Type::SignedInt.into())?;
84		v.encode(&mut self.output)?;
85		Ok(())
86	}
87
88	#[inline]
89	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
90	fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
91		self.output.write_byte(Type::SignedInt.into())?;
92		v.encode(&mut self.output)?;
93		Ok(())
94	}
95
96	#[inline]
97	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
98	fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
99		self.output.write_byte(Type::SignedInt.into())?;
100		v.encode(&mut self.output)?;
101		Ok(())
102	}
103
104	#[inline]
105	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
106	fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
107		self.output.write_byte(Type::SignedInt.into())?;
108		v.encode(&mut self.output)?;
109		Ok(())
110	}
111
112	#[inline]
113	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
114	fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
115		self.output.write_byte(Type::SignedInt.into())?;
116		v.encode(&mut self.output)?;
117		Ok(())
118	}
119
120	#[inline]
121	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
122	fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
123		self.output.write_byte(Type::UnsignedInt.into())?;
124		v.encode(&mut self.output)?;
125		Ok(())
126	}
127
128	#[inline]
129	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
130	fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
131		self.output.write_byte(Type::UnsignedInt.into())?;
132		v.encode(&mut self.output)?;
133		Ok(())
134	}
135
136	#[inline]
137	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
138	fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
139		self.output.write_byte(Type::UnsignedInt.into())?;
140		v.encode(&mut self.output)?;
141		Ok(())
142	}
143
144	#[inline]
145	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
146	fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
147		self.output.write_byte(Type::UnsignedInt.into())?;
148		v.encode(&mut self.output)?;
149		Ok(())
150	}
151
152	#[inline]
153	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
154	fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
155		self.output.write_byte(Type::UnsignedInt.into())?;
156		v.encode(&mut self.output)?;
157		Ok(())
158	}
159
160	#[inline]
161	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
162	fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
163		self.output.write_byte(Type::Float32.into())?;
164		self.output.write_all(&v.to_le_bytes())?;
165		Ok(())
166	}
167
168	#[inline]
169	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
170	fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
171		self.output.write_byte(Type::Float64.into())?;
172		self.output.write_all(&v.to_le_bytes())?;
173		Ok(())
174	}
175
176	#[inline]
177	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
178	fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
179		let mut buffer = [0; 4];
180		let s = v.encode_utf8(&mut buffer);
181		self.serialize_str(s)
182	}
183
184	#[inline]
185	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
186	fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
187		self.output.write_byte(Type::String.into())?;
188		let bytes = v.as_bytes();
189		bytes.len().encode(&mut self.output)?;
190		self.output.write_all(bytes)?;
191		Ok(())
192	}
193
194	#[inline]
195	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
196	fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
197		self.output.write_byte(Type::Bytes.into())?;
198		v.len().encode(&mut self.output)?;
199		self.output.write_all(v)?;
200		Ok(())
201	}
202
203	#[inline]
204	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
205	fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
206		self.output.write_byte(Type::Null.into())?;
207		Ok(())
208	}
209
210	#[inline]
211	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
212	fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
213	where
214		T: ?Sized + serde::Serialize,
215	{
216		value.serialize(self)
217	}
218
219	#[inline]
220	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
221	fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
222		self.output.write_byte(Type::Null.into())?;
223		Ok(())
224	}
225
226	#[inline]
227	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
228	fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
229		self.output.write_byte(Type::Null.into())?;
230		Ok(())
231	}
232
233	#[inline]
234	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
235	fn serialize_unit_variant(
236		self,
237		_name: &'static str,
238		variant_index: u32,
239		variant: &'static str,
240	) -> Result<Self::Ok, Self::Error> {
241		if self.use_indices {
242			variant_index.serialize(self)
243		} else {
244			variant.serialize(self)
245		}
246	}
247
248	#[inline]
249	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
250	fn serialize_newtype_struct<T>(
251		self,
252		_name: &'static str,
253		value: &T,
254	) -> Result<Self::Ok, Self::Error>
255	where
256		T: ?Sized + serde::Serialize,
257	{
258		value.serialize(self)
259	}
260
261	#[inline]
262	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
263	fn serialize_newtype_variant<T>(
264		self,
265		_name: &'static str,
266		variant_index: u32,
267		variant: &'static str,
268		value: &T,
269	) -> Result<Self::Ok, Self::Error>
270	where
271		T: ?Sized + serde::Serialize,
272	{
273		use ::serde::ser::SerializeMap;
274		let use_indices = self.use_indices;
275		let mut map = self.serialize_map(Some(1))?;
276		if use_indices {
277			map.serialize_entry(&variant_index, value)?;
278		} else {
279			map.serialize_entry(variant, value)?;
280		}
281		map.end()?;
282		Ok(())
283	}
284
285	#[inline]
286	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
287	fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
288		self.output.write_byte(Type::SeqStart.into())?;
289		Ok(self)
290	}
291
292	#[inline]
293	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
294	fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
295		self.output.write_byte(Type::SeqStart.into())?;
296		Ok(self)
297	}
298
299	#[inline]
300	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
301	fn serialize_tuple_struct(
302		self,
303		_name: &'static str,
304		_len: usize,
305	) -> Result<Self::SerializeTupleStruct, Self::Error> {
306		self.output.write_byte(Type::SeqStart.into())?;
307		Ok(self)
308	}
309
310	#[inline]
311	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
312	fn serialize_tuple_variant(
313		self,
314		_name: &'static str,
315		variant_index: u32,
316		variant: &'static str,
317		_len: usize,
318	) -> Result<Self::SerializeTupleVariant, Self::Error> {
319		self.output.write_byte(Type::MapStart.into())?;
320		if self.use_indices {
321			variant_index.serialize(&mut *self)?;
322		} else {
323			variant.serialize(&mut *self)?;
324		}
325		self.output.write_byte(Type::SeqStart.into())?;
326		Ok(self)
327	}
328
329	#[inline]
330	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
331	fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
332		self.output.write_byte(Type::MapStart.into())?;
333		Ok(self)
334	}
335
336	#[inline]
337	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
338	fn serialize_struct(
339		self,
340		_name: &'static str,
341		_len: usize,
342	) -> Result<Self::SerializeStruct, Self::Error> {
343		self.output.write_byte(Type::MapStart.into())?;
344		Ok(StructSerializer::new(self))
345	}
346
347	#[inline]
348	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
349	fn serialize_struct_variant(
350		self,
351		_name: &'static str,
352		variant_index: u32,
353		variant: &'static str,
354		_len: usize,
355	) -> Result<Self::SerializeStructVariant, Self::Error> {
356		self.output.write_byte(Type::MapStart.into())?;
357		if self.use_indices {
358			variant_index.serialize(&mut *self)?;
359		} else {
360			variant.serialize(&mut *self)?;
361		}
362		self.output.write_byte(Type::MapStart.into())?;
363		Ok(StructSerializer::new(self))
364	}
365
366	#[cfg(feature = "alloc")]
367	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
368	fn collect_str<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
369	where
370		T: ?Sized + core::fmt::Display,
371	{
372		let s = ::alloc::string::ToString::to_string(value);
373		self.serialize_str(&s)
374	}
375
376	#[cfg(not(feature = "alloc"))]
377	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
378	fn collect_str<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
379	where
380		T: ?Sized + core::fmt::Display,
381	{
382		use ::core::fmt::Write;
383
384		/// A writer that counts the number of bytes written.
385		struct CountWriter(usize);
386		impl Write for CountWriter {
387			fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
388				self.0 += s.len();
389				Ok(())
390			}
391		}
392
393		/// A writer that writes the formatted string into the output.
394		struct OutputWriter<'a, O>(&'a mut O);
395		impl<'a, O: Output> Write for OutputWriter<'a, O> {
396			fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
397				self.0.write_all(s.as_bytes()).map_err(|_| ::core::fmt::Error)
398			}
399		}
400
401		// Pass through once to get the string length.
402		let mut counter = CountWriter(0);
403		write!(&mut counter, "{value}")?;
404		let len = counter.0;
405		self.output.write_byte(Type::String.into())?;
406		len.encode(&mut self.output)?;
407
408		// Second pass to actually write the data.
409		let mut writer = OutputWriter(&mut self.output);
410		write!(&mut writer, "{value}")?;
411
412		Ok(())
413	}
414}
415
416impl<'a, O> ::serde::ser::SerializeSeq for &'a mut Serializer<O>
417where
418	O: Output,
419{
420	type Ok = ();
421	type Error = Error;
422
423	#[inline]
424	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
425	fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
426	where
427		T: ?Sized + serde::Serialize,
428	{
429		value.serialize(&mut **self)
430	}
431
432	#[inline]
433	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
434	fn end(self) -> Result<Self::Ok, Self::Error> {
435		self.output.write_byte(Type::SeqEnd.into())?;
436		Ok(())
437	}
438}
439
440impl<'a, O> ::serde::ser::SerializeTuple for &'a mut Serializer<O>
441where
442	O: Output,
443{
444	type Ok = ();
445	type Error = Error;
446
447	#[inline]
448	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
449	fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
450	where
451		T: ?Sized + serde::Serialize,
452	{
453		value.serialize(&mut **self)
454	}
455
456	#[inline]
457	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
458	fn end(self) -> Result<Self::Ok, Self::Error> {
459		self.output.write_byte(Type::SeqEnd.into())?;
460		Ok(())
461	}
462}
463
464impl<'a, O> ::serde::ser::SerializeTupleStruct for &'a mut Serializer<O>
465where
466	O: Output,
467{
468	type Ok = ();
469	type Error = Error;
470
471	#[inline]
472	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
473	fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
474	where
475		T: ?Sized + serde::Serialize,
476	{
477		value.serialize(&mut **self)
478	}
479
480	#[inline]
481	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
482	fn end(self) -> Result<Self::Ok, Self::Error> {
483		self.output.write_byte(Type::SeqEnd.into())?;
484		Ok(())
485	}
486}
487
488impl<'a, O> ::serde::ser::SerializeTupleVariant for &'a mut Serializer<O>
489where
490	O: Output,
491{
492	type Ok = ();
493	type Error = Error;
494
495	#[inline]
496	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
497	fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
498	where
499		T: ?Sized + serde::Serialize,
500	{
501		value.serialize(&mut **self)
502	}
503
504	#[inline]
505	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
506	fn end(self) -> Result<Self::Ok, Self::Error> {
507		self.output.write_byte(Type::SeqEnd.into())?;
508		self.output.write_byte(Type::MapEnd.into())?;
509		Ok(())
510	}
511}
512
513impl<'a, O> ::serde::ser::SerializeMap for &'a mut Serializer<O>
514where
515	O: Output,
516{
517	type Ok = ();
518	type Error = Error;
519
520	#[inline]
521	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
522	fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
523	where
524		T: ?Sized + serde::Serialize,
525	{
526		key.serialize(&mut **self)
527	}
528
529	#[inline]
530	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
531	fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
532	where
533		T: ?Sized + serde::Serialize,
534	{
535		value.serialize(&mut **self)
536	}
537
538	#[inline]
539	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
540	fn end(self) -> Result<Self::Ok, Self::Error> {
541		self.output.write_byte(Type::MapEnd.into())?;
542		Ok(())
543	}
544
545	#[inline]
546	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
547	fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
548	where
549		K: ?Sized + serde::Serialize,
550		V: ?Sized + serde::Serialize,
551	{
552		self.serialize_key(key)?;
553		self.serialize_value(value)
554	}
555}
556
557/// Struct serializer that keeps track of the field index.
558#[derive(Debug)]
559pub struct StructSerializer<'a, O> {
560	/// The inner serializer.
561	serializer: &'a mut Serializer<O>,
562	/// The current field index.
563	field_index: u32,
564}
565
566impl<'a, O> StructSerializer<'a, O> {
567	/// Create a new struct serializer.
568	#[must_use]
569	fn new(serializer: &'a mut Serializer<O>) -> Self {
570		Self { serializer, field_index: 0 }
571	}
572}
573
574impl<'a, O> ::serde::ser::SerializeStruct for StructSerializer<'a, O>
575where
576	O: Output,
577{
578	type Ok = ();
579	type Error = Error;
580
581	#[inline]
582	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
583	fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
584	where
585		T: ?Sized + serde::Serialize,
586	{
587		if self.serializer.use_indices {
588			self.field_index.serialize(&mut *self.serializer)?;
589		} else {
590			key.serialize(&mut *self.serializer)?;
591		}
592		self.field_index += 1;
593		value.serialize(&mut *self.serializer)
594	}
595
596	#[inline]
597	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
598	fn end(self) -> Result<Self::Ok, Self::Error> {
599		self.serializer.output.write_byte(Type::MapEnd.into())?;
600		Ok(())
601	}
602
603	#[inline]
604	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
605	fn skip_field(&mut self, _key: &'static str) -> Result<(), Self::Error> {
606		self.field_index += 1;
607		Ok(())
608	}
609}
610
611impl<'a, O> ::serde::ser::SerializeStructVariant for StructSerializer<'a, O>
612where
613	O: Output,
614{
615	type Ok = ();
616	type Error = Error;
617
618	#[inline]
619	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
620	fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
621	where
622		T: ?Sized + Serialize,
623	{
624		if self.serializer.use_indices {
625			self.field_index.serialize(&mut *self.serializer)?;
626		} else {
627			key.serialize(&mut *self.serializer)?;
628		}
629		self.field_index += 1;
630		value.serialize(&mut *self.serializer)
631	}
632
633	#[inline]
634	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
635	fn end(self) -> Result<Self::Ok, Self::Error> {
636		self.serializer.output.write_byte(Type::MapEnd.into())?;
637		self.serializer.output.write_byte(Type::MapEnd.into())?;
638		Ok(())
639	}
640
641	#[inline]
642	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
643	fn skip_field(&mut self, _key: &'static str) -> Result<(), Self::Error> {
644		self.field_index += 1;
645		Ok(())
646	}
647}