Skip to main content

bincode_next/enc/
impls.rs

1#![allow(unsafe_code)]
2use super::Encode;
3use super::Encoder;
4use super::write::Writer;
5use crate::error::EncodeError;
6use core::cell::Cell;
7use core::cell::RefCell;
8use core::cmp::Reverse;
9use core::marker::PhantomData;
10use core::num::NonZeroI8;
11use core::num::NonZeroI16;
12use core::num::NonZeroI32;
13use core::num::NonZeroI64;
14use core::num::NonZeroI128;
15use core::num::NonZeroIsize;
16use core::num::NonZeroU8;
17use core::num::NonZeroU16;
18use core::num::NonZeroU32;
19use core::num::NonZeroU64;
20use core::num::NonZeroU128;
21use core::num::NonZeroUsize;
22use core::num::Wrapping;
23use core::ops::Bound;
24use core::ops::Range;
25use core::ops::RangeInclusive;
26use core::time::Duration;
27
28impl Encode for () {
29    #[inline(always)]
30    fn encode<E: Encoder>(
31        &self,
32        _: &mut E,
33    ) -> Result<(), EncodeError> {
34        Ok(())
35    }
36}
37
38impl<T> Encode for PhantomData<T> {
39    #[inline(always)]
40    fn encode<E: Encoder>(
41        &self,
42        _: &mut E,
43    ) -> Result<(), EncodeError> {
44        Ok(())
45    }
46}
47
48impl Encode for bool {
49    #[inline(always)]
50    fn encode<E: Encoder>(
51        &self,
52        encoder: &mut E,
53    ) -> Result<(), EncodeError> {
54        encoder.encode_bool(*self)
55    }
56}
57
58impl Encode for u8 {
59    #[inline(always)]
60    fn encode<E: Encoder>(
61        &self,
62        encoder: &mut E,
63    ) -> Result<(), EncodeError> {
64        encoder.encode_u8(*self)
65    }
66}
67
68impl Encode for NonZeroU8 {
69    #[inline(always)]
70    fn encode<E: Encoder>(
71        &self,
72        encoder: &mut E,
73    ) -> Result<(), EncodeError> {
74        self.get().encode(encoder)
75    }
76}
77
78impl Encode for u16 {
79    #[inline(always)]
80    fn encode<E: Encoder>(
81        &self,
82        encoder: &mut E,
83    ) -> Result<(), EncodeError> {
84        encoder.encode_u16(*self)
85    }
86}
87
88impl Encode for NonZeroU16 {
89    #[inline(always)]
90    fn encode<E: Encoder>(
91        &self,
92        encoder: &mut E,
93    ) -> Result<(), EncodeError> {
94        self.get().encode(encoder)
95    }
96}
97
98impl Encode for u32 {
99    #[inline(always)]
100    fn encode<E: Encoder>(
101        &self,
102        encoder: &mut E,
103    ) -> Result<(), EncodeError> {
104        encoder.encode_u32(*self)
105    }
106}
107
108impl Encode for NonZeroU32 {
109    #[inline(always)]
110    fn encode<E: Encoder>(
111        &self,
112        encoder: &mut E,
113    ) -> Result<(), EncodeError> {
114        self.get().encode(encoder)
115    }
116}
117
118impl Encode for u64 {
119    #[inline(always)]
120    fn encode<E: Encoder>(
121        &self,
122        encoder: &mut E,
123    ) -> Result<(), EncodeError> {
124        encoder.encode_u64(*self)
125    }
126}
127
128impl Encode for NonZeroU64 {
129    #[inline(always)]
130    fn encode<E: Encoder>(
131        &self,
132        encoder: &mut E,
133    ) -> Result<(), EncodeError> {
134        self.get().encode(encoder)
135    }
136}
137
138impl Encode for u128 {
139    #[inline(always)]
140    fn encode<E: Encoder>(
141        &self,
142        encoder: &mut E,
143    ) -> Result<(), EncodeError> {
144        encoder.encode_u128(*self)
145    }
146}
147
148impl Encode for NonZeroU128 {
149    #[inline(always)]
150    fn encode<E: Encoder>(
151        &self,
152        encoder: &mut E,
153    ) -> Result<(), EncodeError> {
154        self.get().encode(encoder)
155    }
156}
157
158impl Encode for usize {
159    #[inline(always)]
160    fn encode<E: Encoder>(
161        &self,
162        encoder: &mut E,
163    ) -> Result<(), EncodeError> {
164        encoder.encode_usize(*self)
165    }
166}
167
168impl Encode for NonZeroUsize {
169    #[inline(always)]
170    fn encode<E: Encoder>(
171        &self,
172        encoder: &mut E,
173    ) -> Result<(), EncodeError> {
174        self.get().encode(encoder)
175    }
176}
177
178impl Encode for i8 {
179    #[inline(always)]
180    fn encode<E: Encoder>(
181        &self,
182        encoder: &mut E,
183    ) -> Result<(), EncodeError> {
184        encoder.encode_i8(*self)
185    }
186}
187
188impl Encode for NonZeroI8 {
189    #[inline(always)]
190    fn encode<E: Encoder>(
191        &self,
192        encoder: &mut E,
193    ) -> Result<(), EncodeError> {
194        self.get().encode(encoder)
195    }
196}
197
198impl Encode for i16 {
199    #[inline(always)]
200    fn encode<E: Encoder>(
201        &self,
202        encoder: &mut E,
203    ) -> Result<(), EncodeError> {
204        encoder.encode_i16(*self)
205    }
206}
207
208impl Encode for NonZeroI16 {
209    #[inline(always)]
210    fn encode<E: Encoder>(
211        &self,
212        encoder: &mut E,
213    ) -> Result<(), EncodeError> {
214        self.get().encode(encoder)
215    }
216}
217
218impl Encode for i32 {
219    #[inline(always)]
220    fn encode<E: Encoder>(
221        &self,
222        encoder: &mut E,
223    ) -> Result<(), EncodeError> {
224        encoder.encode_i32(*self)
225    }
226}
227
228impl Encode for NonZeroI32 {
229    #[inline(always)]
230    fn encode<E: Encoder>(
231        &self,
232        encoder: &mut E,
233    ) -> Result<(), EncodeError> {
234        self.get().encode(encoder)
235    }
236}
237
238impl Encode for i64 {
239    #[inline(always)]
240    fn encode<E: Encoder>(
241        &self,
242        encoder: &mut E,
243    ) -> Result<(), EncodeError> {
244        encoder.encode_i64(*self)
245    }
246}
247
248impl Encode for NonZeroI64 {
249    #[inline(always)]
250    fn encode<E: Encoder>(
251        &self,
252        encoder: &mut E,
253    ) -> Result<(), EncodeError> {
254        self.get().encode(encoder)
255    }
256}
257
258impl Encode for i128 {
259    #[inline(always)]
260    fn encode<E: Encoder>(
261        &self,
262        encoder: &mut E,
263    ) -> Result<(), EncodeError> {
264        encoder.encode_i128(*self)
265    }
266}
267
268impl Encode for NonZeroI128 {
269    #[inline(always)]
270    fn encode<E: Encoder>(
271        &self,
272        encoder: &mut E,
273    ) -> Result<(), EncodeError> {
274        self.get().encode(encoder)
275    }
276}
277
278impl Encode for isize {
279    #[inline(always)]
280    fn encode<E: Encoder>(
281        &self,
282        encoder: &mut E,
283    ) -> Result<(), EncodeError> {
284        encoder.encode_isize(*self)
285    }
286}
287
288impl Encode for NonZeroIsize {
289    #[inline(always)]
290    fn encode<E: Encoder>(
291        &self,
292        encoder: &mut E,
293    ) -> Result<(), EncodeError> {
294        self.get().encode(encoder)
295    }
296}
297
298impl Encode for f32 {
299    #[inline(always)]
300    fn encode<E: Encoder>(
301        &self,
302        encoder: &mut E,
303    ) -> Result<(), EncodeError> {
304        encoder.encode_f32(*self)
305    }
306}
307
308impl Encode for f64 {
309    #[inline(always)]
310    fn encode<E: Encoder>(
311        &self,
312        encoder: &mut E,
313    ) -> Result<(), EncodeError> {
314        encoder.encode_f64(*self)
315    }
316}
317
318impl<T: Encode> Encode for Wrapping<T> {
319    #[inline(always)]
320    fn encode<E: Encoder>(
321        &self,
322        encoder: &mut E,
323    ) -> Result<(), EncodeError> {
324        self.0.encode(encoder)
325    }
326}
327
328impl<T: Encode> Encode for Reverse<T> {
329    #[inline(always)]
330    fn encode<E: Encoder>(
331        &self,
332        encoder: &mut E,
333    ) -> Result<(), EncodeError> {
334        self.0.encode(encoder)
335    }
336}
337
338impl Encode for char {
339    #[inline(always)]
340    fn encode<E: Encoder>(
341        &self,
342        encoder: &mut E,
343    ) -> Result<(), EncodeError> {
344        encode_utf8(encoder.writer(), *self)
345    }
346}
347
348impl<T> Encode for [T]
349where
350    T: Encode,
351{
352    #[inline]
353    fn encode<E: Encoder>(
354        &self,
355        encoder: &mut E,
356    ) -> Result<(), EncodeError> {
357        let is_u8 = unty::type_equal::<T, u8>() || unty::type_equal::<T, i8>();
358        if is_u8 {
359            // SAFETY: self is [T], and T is u8/i8, so it's safe to cast to [u8]
360            let bytes =
361                unsafe { core::slice::from_raw_parts(self.as_ptr().cast::<u8>(), self.len()) };
362            return encoder.encode_byte_slice(bytes);
363        }
364
365        super::encode_slice_len(encoder, self.len())?;
366
367        let is_fixed = matches!(
368            <E::C as crate::config::InternalIntEncodingConfig>::INT_ENCODING,
369            crate::config::IntEncoding::Fixed
370        );
371        let is_native_endian = match <E::C as crate::config::InternalEndianConfig>::ENDIAN {
372            | crate::config::Endianness::Little => cfg!(target_endian = "little"),
373            | crate::config::Endianness::Big => cfg!(target_endian = "big"),
374        };
375        let is_bincode = matches!(
376            <E::C as crate::config::InternalFormatConfig>::FORMAT,
377            crate::config::Format::Bincode | crate::config::Format::BincodeDeterministic
378        );
379
380        if is_bincode
381            && (is_native_endian
382                && (unty::type_equal::<T, f32>()
383                    || unty::type_equal::<T, f64>()
384                    || (is_fixed
385                        && (unty::type_equal::<T, u16>()
386                            || unty::type_equal::<T, i16>()
387                            || unty::type_equal::<T, u32>()
388                            || unty::type_equal::<T, i32>()
389                            || unty::type_equal::<T, u64>()
390                            || unty::type_equal::<T, i64>()
391                            || unty::type_equal::<T, u128>()
392                            || unty::type_equal::<T, i128>()))))
393        {
394            let bytes_to_copy = core::mem::size_of_val(self);
395            // SAFETY: T is a primitive type (pod), so it's safe to copy its bytes.
396            // We've checked that the encoding is Fixed and Endianness matches.
397            unsafe {
398                let slice_ptr = self.as_ptr().cast::<u8>();
399                let slice = core::slice::from_raw_parts(slice_ptr, bytes_to_copy);
400                encoder.writer().write(slice)?;
401            }
402            return Ok(());
403        }
404
405        for item in self {
406            item.encode(encoder)?;
407        }
408        Ok(())
409    }
410}
411
412const TAG_CONT: u8 = 0b1000_0000;
413const TAG_TWO_B: u8 = 0b1100_0000;
414const TAG_THREE_B: u8 = 0b1110_0000;
415const TAG_FOUR_B: u8 = 0b1111_0000;
416const MAX_ONE_B: u32 = 0x80;
417const MAX_TWO_B: u32 = 0x800;
418const MAX_THREE_B: u32 = 0x10000;
419
420#[inline(always)]
421fn encode_utf8(
422    writer: &mut impl Writer,
423    c: char,
424) -> Result<(), EncodeError> {
425    let code = c as u32;
426
427    if code < MAX_ONE_B {
428        writer.write_u8(c as u8)
429    } else if code < MAX_TWO_B {
430        let mut buf = [0u8; 2];
431        buf[0] = ((code >> 6) & 0x1F) as u8 | TAG_TWO_B;
432        buf[1] = (code & 0x3F) as u8 | TAG_CONT;
433        writer.write(&buf)
434    } else if code < MAX_THREE_B {
435        let mut buf = [0u8; 3];
436        buf[0] = ((code >> 12) & 0x0F) as u8 | TAG_THREE_B;
437        buf[1] = ((code >> 6) & 0x3F) as u8 | TAG_CONT;
438        buf[2] = (code & 0x3F) as u8 | TAG_CONT;
439        writer.write(&buf)
440    } else {
441        let mut buf = [0u8; 4];
442        buf[0] = ((code >> 18) & 0x07) as u8 | TAG_FOUR_B;
443        buf[1] = ((code >> 12) & 0x3F) as u8 | TAG_CONT;
444        buf[2] = ((code >> 6) & 0x3F) as u8 | TAG_CONT;
445        buf[3] = (code & 0x3F) as u8 | TAG_CONT;
446        writer.write(&buf)
447    }
448}
449
450impl Encode for str {
451    #[inline(always)]
452    fn encode<E: Encoder>(
453        &self,
454        encoder: &mut E,
455    ) -> Result<(), EncodeError> {
456        encoder.encode_str(self)
457    }
458}
459
460impl<T, const N: usize> Encode for [T; N]
461where
462    T: Encode,
463{
464    #[inline]
465    fn encode<E: Encoder>(
466        &self,
467        encoder: &mut E,
468    ) -> Result<(), EncodeError> {
469        let is_u8 = unty::type_equal::<T, u8>() || unty::type_equal::<T, i8>();
470        let is_bincode = matches!(
471            <E::C as crate::config::InternalFormatConfig>::FORMAT,
472            crate::config::Format::Bincode | crate::config::Format::BincodeDeterministic
473        );
474
475        if is_u8 && !is_bincode {
476            // SAFETY: self is [T; N], T is u8/i8, so it's safe to cast to [u8]
477            let bytes = unsafe { core::slice::from_raw_parts(self.as_ptr().cast::<u8>(), N) };
478            return encoder.encode_byte_slice(bytes);
479        }
480
481        let is_fixed = matches!(
482            <E::C as crate::config::InternalIntEncodingConfig>::INT_ENCODING,
483            crate::config::IntEncoding::Fixed
484        );
485        let is_native_endian = match <E::C as crate::config::InternalEndianConfig>::ENDIAN {
486            | crate::config::Endianness::Little => cfg!(target_endian = "little"),
487            | crate::config::Endianness::Big => cfg!(target_endian = "big"),
488        };
489
490        if is_bincode
491            && (is_u8
492                || (is_native_endian
493                    && (unty::type_equal::<T, f32>()
494                        || unty::type_equal::<T, f64>()
495                        || (is_fixed
496                            && (unty::type_equal::<T, u16>()
497                                || unty::type_equal::<T, i16>()
498                                || unty::type_equal::<T, u32>()
499                                || unty::type_equal::<T, i32>()
500                                || unty::type_equal::<T, u64>()
501                                || unty::type_equal::<T, i64>()
502                                || unty::type_equal::<T, u128>()
503                                || unty::type_equal::<T, i128>())))))
504        {
505            let bytes_to_copy = N * core::mem::size_of::<T>();
506            // SAFETY: T is a primitive type (pod), so it's safe to copy its bytes.
507            // We've checked that the encoding is Fixed and Endianness matches,
508            // or that it's a 1-byte type (u8/i8).
509            unsafe {
510                let slice_ptr = self.as_ptr().cast::<u8>();
511                let slice = core::slice::from_raw_parts(slice_ptr, bytes_to_copy);
512                encoder.writer().write(slice)?;
513            }
514        } else {
515            if !is_bincode {
516                encoder.encode_array_len(N)?;
517            }
518            for item in self {
519                item.encode(encoder)?;
520            }
521        }
522        Ok(())
523    }
524}
525
526impl<T> Encode for Option<T>
527where
528    T: Encode,
529{
530    #[inline(always)]
531    fn encode<E: Encoder>(
532        &self,
533        encoder: &mut E,
534    ) -> Result<(), EncodeError> {
535        super::encode_option_variant(encoder, self.as_ref())?;
536        if let Some(val) = self {
537            val.encode(encoder)?;
538        }
539        Ok(())
540    }
541}
542
543impl<T, U> Encode for Result<T, U>
544where
545    T: Encode,
546    U: Encode,
547{
548    #[inline(always)]
549    fn encode<E: Encoder>(
550        &self,
551        encoder: &mut E,
552    ) -> Result<(), EncodeError> {
553        match self {
554            | Ok(val) => {
555                encoder.encode_variant_index(0)?;
556                val.encode(encoder)
557            },
558            | Err(err) => {
559                encoder.encode_variant_index(1)?;
560                err.encode(encoder)
561            },
562        }
563    }
564}
565
566impl<T> Encode for Cell<T>
567where
568    T: Encode + Copy,
569{
570    #[inline(always)]
571    fn encode<E: Encoder>(
572        &self,
573        encoder: &mut E,
574    ) -> Result<(), EncodeError> {
575        T::encode(&self.get(), encoder)
576    }
577}
578
579impl<T> Encode for RefCell<T>
580where
581    T: Encode + ?Sized,
582{
583    #[inline(always)]
584    fn encode<E: Encoder>(
585        &self,
586        encoder: &mut E,
587    ) -> Result<(), EncodeError> {
588        let borrow_guard = self.try_borrow().map_err(|e| {
589            crate::error::cold_encode_error_ref_cell_already_borrowed::<()>(
590                e,
591                core::any::type_name::<Self>(),
592            )
593            .unwrap_err()
594        })?;
595        T::encode(&borrow_guard, encoder)
596    }
597}
598
599impl Encode for Duration {
600    #[inline(always)]
601    fn encode<E: Encoder>(
602        &self,
603        encoder: &mut E,
604    ) -> Result<(), EncodeError> {
605        self.as_secs().encode(encoder)?;
606        self.subsec_nanos().encode(encoder)?;
607        Ok(())
608    }
609}
610
611impl<T> Encode for Range<T>
612where
613    T: Encode,
614{
615    #[inline(always)]
616    fn encode<E: Encoder>(
617        &self,
618        encoder: &mut E,
619    ) -> Result<(), EncodeError> {
620        self.start.encode(encoder)?;
621        self.end.encode(encoder)?;
622        Ok(())
623    }
624}
625
626impl<T> Encode for RangeInclusive<T>
627where
628    T: Encode,
629{
630    #[inline(always)]
631    fn encode<E: Encoder>(
632        &self,
633        encoder: &mut E,
634    ) -> Result<(), EncodeError> {
635        self.start().encode(encoder)?;
636        self.end().encode(encoder)?;
637        Ok(())
638    }
639}
640
641impl<T> Encode for Bound<T>
642where
643    T: Encode,
644{
645    #[inline(always)]
646    fn encode<E: Encoder>(
647        &self,
648        encoder: &mut E,
649    ) -> Result<(), EncodeError> {
650        match self {
651            | Self::Unbounded => {
652                0u32.encode(encoder)?;
653            },
654            | Self::Included(val) => {
655                1u32.encode(encoder)?;
656                val.encode(encoder)?;
657            },
658            | Self::Excluded(val) => {
659                2u32.encode(encoder)?;
660                val.encode(encoder)?;
661            },
662        }
663        Ok(())
664    }
665}
666
667impl<T> Encode for &T
668where
669    T: Encode + ?Sized,
670{
671    #[inline(always)]
672    fn encode<E: Encoder>(
673        &self,
674        encoder: &mut E,
675    ) -> Result<(), EncodeError> {
676        T::encode(self, encoder)
677    }
678}