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	Config, Error,
11	format::{Type, VarInt},
12	io::Output,
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 { variant_index.serialize(self) } else { variant.serialize(self) }
242	}
243
244	#[inline]
245	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
246	fn serialize_newtype_struct<T>(
247		self,
248		_name: &'static str,
249		value: &T,
250	) -> Result<Self::Ok, Self::Error>
251	where
252		T: ?Sized + serde::Serialize,
253	{
254		value.serialize(self)
255	}
256
257	#[inline]
258	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
259	fn serialize_newtype_variant<T>(
260		self,
261		_name: &'static str,
262		variant_index: u32,
263		variant: &'static str,
264		value: &T,
265	) -> Result<Self::Ok, Self::Error>
266	where
267		T: ?Sized + serde::Serialize,
268	{
269		use ::serde::ser::SerializeMap;
270		let use_indices = self.use_indices;
271		let mut map = self.serialize_map(Some(1))?;
272		if use_indices {
273			map.serialize_entry(&variant_index, value)?;
274		} else {
275			map.serialize_entry(variant, value)?;
276		}
277		map.end()?;
278		Ok(())
279	}
280
281	#[inline]
282	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
283	fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
284		self.output.write_byte(Type::SeqStart.into())?;
285		Ok(self)
286	}
287
288	#[inline]
289	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
290	fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
291		self.output.write_byte(Type::SeqStart.into())?;
292		Ok(self)
293	}
294
295	#[inline]
296	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
297	fn serialize_tuple_struct(
298		self,
299		_name: &'static str,
300		_len: usize,
301	) -> Result<Self::SerializeTupleStruct, Self::Error> {
302		self.output.write_byte(Type::SeqStart.into())?;
303		Ok(self)
304	}
305
306	#[inline]
307	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
308	fn serialize_tuple_variant(
309		self,
310		_name: &'static str,
311		variant_index: u32,
312		variant: &'static str,
313		_len: usize,
314	) -> Result<Self::SerializeTupleVariant, Self::Error> {
315		self.output.write_byte(Type::MapStart.into())?;
316		if self.use_indices {
317			variant_index.serialize(&mut *self)?;
318		} else {
319			variant.serialize(&mut *self)?;
320		}
321		self.output.write_byte(Type::SeqStart.into())?;
322		Ok(self)
323	}
324
325	#[inline]
326	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
327	fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
328		self.output.write_byte(Type::MapStart.into())?;
329		Ok(self)
330	}
331
332	#[inline]
333	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
334	fn serialize_struct(
335		self,
336		_name: &'static str,
337		_len: usize,
338	) -> Result<Self::SerializeStruct, Self::Error> {
339		self.output.write_byte(Type::MapStart.into())?;
340		Ok(StructSerializer::new(self))
341	}
342
343	#[inline]
344	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
345	fn serialize_struct_variant(
346		self,
347		_name: &'static str,
348		variant_index: u32,
349		variant: &'static str,
350		_len: usize,
351	) -> Result<Self::SerializeStructVariant, Self::Error> {
352		self.output.write_byte(Type::MapStart.into())?;
353		if self.use_indices {
354			variant_index.serialize(&mut *self)?;
355		} else {
356			variant.serialize(&mut *self)?;
357		}
358		self.output.write_byte(Type::MapStart.into())?;
359		Ok(StructSerializer::new(self))
360	}
361
362	#[cfg(feature = "alloc")]
363	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
364	fn collect_str<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
365	where
366		T: ?Sized + core::fmt::Display,
367	{
368		let s = ::alloc::string::ToString::to_string(value);
369		self.serialize_str(&s)
370	}
371
372	#[cfg(not(feature = "alloc"))]
373	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
374	fn collect_str<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
375	where
376		T: ?Sized + core::fmt::Display,
377	{
378		use ::core::fmt::Write;
379
380		/// A writer that counts the number of bytes written.
381		struct CountWriter(usize);
382		impl Write for CountWriter {
383			fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
384				self.0 += s.len();
385				Ok(())
386			}
387		}
388
389		/// A writer that writes the formatted string into the output.
390		struct OutputWriter<'a, O>(&'a mut O);
391		impl<O: Output> Write for OutputWriter<'_, O> {
392			fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
393				self.0.write_all(s.as_bytes()).map_err(|_| ::core::fmt::Error)
394			}
395		}
396
397		// Pass through once to get the string length.
398		let mut counter = CountWriter(0);
399		write!(&mut counter, "{value}")?;
400		let len = counter.0;
401		self.output.write_byte(Type::String.into())?;
402		len.encode(&mut self.output)?;
403
404		// Second pass to actually write the data.
405		let mut writer = OutputWriter(&mut self.output);
406		write!(&mut writer, "{value}")?;
407
408		Ok(())
409	}
410}
411
412impl<O> ::serde::ser::SerializeSeq for &mut Serializer<O>
413where
414	O: Output,
415{
416	type Ok = ();
417	type Error = Error;
418
419	#[inline]
420	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
421	fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
422	where
423		T: ?Sized + serde::Serialize,
424	{
425		value.serialize(&mut **self)
426	}
427
428	#[inline]
429	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
430	fn end(self) -> Result<Self::Ok, Self::Error> {
431		self.output.write_byte(Type::SeqEnd.into())?;
432		Ok(())
433	}
434}
435
436impl<O> ::serde::ser::SerializeTuple for &mut Serializer<O>
437where
438	O: Output,
439{
440	type Ok = ();
441	type Error = Error;
442
443	#[inline]
444	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
445	fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
446	where
447		T: ?Sized + serde::Serialize,
448	{
449		value.serialize(&mut **self)
450	}
451
452	#[inline]
453	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
454	fn end(self) -> Result<Self::Ok, Self::Error> {
455		self.output.write_byte(Type::SeqEnd.into())?;
456		Ok(())
457	}
458}
459
460impl<O> ::serde::ser::SerializeTupleStruct for &mut Serializer<O>
461where
462	O: Output,
463{
464	type Ok = ();
465	type Error = Error;
466
467	#[inline]
468	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
469	fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
470	where
471		T: ?Sized + serde::Serialize,
472	{
473		value.serialize(&mut **self)
474	}
475
476	#[inline]
477	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
478	fn end(self) -> Result<Self::Ok, Self::Error> {
479		self.output.write_byte(Type::SeqEnd.into())?;
480		Ok(())
481	}
482}
483
484impl<O> ::serde::ser::SerializeTupleVariant for &mut Serializer<O>
485where
486	O: Output,
487{
488	type Ok = ();
489	type Error = Error;
490
491	#[inline]
492	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
493	fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
494	where
495		T: ?Sized + serde::Serialize,
496	{
497		value.serialize(&mut **self)
498	}
499
500	#[inline]
501	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
502	fn end(self) -> Result<Self::Ok, Self::Error> {
503		self.output.write_byte(Type::SeqEnd.into())?;
504		self.output.write_byte(Type::MapEnd.into())?;
505		Ok(())
506	}
507}
508
509impl<O> ::serde::ser::SerializeMap for &mut Serializer<O>
510where
511	O: Output,
512{
513	type Ok = ();
514	type Error = Error;
515
516	#[inline]
517	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
518	fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
519	where
520		T: ?Sized + serde::Serialize,
521	{
522		key.serialize(&mut **self)
523	}
524
525	#[inline]
526	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
527	fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
528	where
529		T: ?Sized + serde::Serialize,
530	{
531		value.serialize(&mut **self)
532	}
533
534	#[inline]
535	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
536	fn end(self) -> Result<Self::Ok, Self::Error> {
537		self.output.write_byte(Type::MapEnd.into())?;
538		Ok(())
539	}
540
541	#[inline]
542	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
543	fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
544	where
545		K: ?Sized + serde::Serialize,
546		V: ?Sized + serde::Serialize,
547	{
548		self.serialize_key(key)?;
549		self.serialize_value(value)
550	}
551}
552
553/// Struct serializer that keeps track of the field index.
554#[derive(Debug)]
555pub struct StructSerializer<'a, O> {
556	/// The inner serializer.
557	serializer: &'a mut Serializer<O>,
558	/// The current field index.
559	field_index: u32,
560}
561
562impl<'a, O> StructSerializer<'a, O> {
563	/// Create a new struct serializer.
564	#[must_use]
565	const fn new(serializer: &'a mut Serializer<O>) -> Self {
566		Self { serializer, field_index: 0 }
567	}
568}
569
570impl<O> ::serde::ser::SerializeStruct for StructSerializer<'_, O>
571where
572	O: Output,
573{
574	type Ok = ();
575	type Error = Error;
576
577	#[inline]
578	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
579	fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
580	where
581		T: ?Sized + serde::Serialize,
582	{
583		if self.serializer.use_indices {
584			self.field_index.serialize(&mut *self.serializer)?;
585		} else {
586			key.serialize(&mut *self.serializer)?;
587		}
588		self.field_index += 1;
589		value.serialize(&mut *self.serializer)
590	}
591
592	#[inline]
593	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
594	fn end(self) -> Result<Self::Ok, Self::Error> {
595		self.serializer.output.write_byte(Type::MapEnd.into())?;
596		Ok(())
597	}
598
599	#[inline]
600	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
601	fn skip_field(&mut self, _key: &'static str) -> Result<(), Self::Error> {
602		self.field_index += 1;
603		Ok(())
604	}
605}
606
607impl<O> ::serde::ser::SerializeStructVariant for StructSerializer<'_, O>
608where
609	O: Output,
610{
611	type Ok = ();
612	type Error = Error;
613
614	#[inline]
615	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, value)))]
616	fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
617	where
618		T: ?Sized + Serialize,
619	{
620		if self.serializer.use_indices {
621			self.field_index.serialize(&mut *self.serializer)?;
622		} else {
623			key.serialize(&mut *self.serializer)?;
624		}
625		self.field_index += 1;
626		value.serialize(&mut *self.serializer)
627	}
628
629	#[inline]
630	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
631	fn end(self) -> Result<Self::Ok, Self::Error> {
632		self.serializer.output.write_byte(Type::MapEnd.into())?;
633		self.serializer.output.write_byte(Type::MapEnd.into())?;
634		Ok(())
635	}
636
637	#[inline]
638	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self)))]
639	fn skip_field(&mut self, _key: &'static str) -> Result<(), Self::Error> {
640		self.field_index += 1;
641		Ok(())
642	}
643}