Skip to main content

rustolio_utils/bytes/encoding/
encode.rs

1//
2// SPDX-License-Identifier: MPL-2.0
3//
4// Copyright (c) 2026 Tobias Binnewies. All rights reserved.
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9//
10
11use crate::prelude::*;
12
13use super::{transmute_slice, type_eq};
14
15pub trait Encode {
16    fn encode_size(&self) -> usize;
17    fn encode(&self, writer: &mut impl Encoder) -> crate::Result<()>;
18
19    #[allow(async_fn_in_trait)] // Auto-Traits should not be specified as this leads to problems in web-code (where all types are `!Send`) and server code (where tokio::spawn needs all futures to be `Send`)
20    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()>;
21}
22
23pub trait Encoder: Unpin {
24    fn write_u8(&mut self, byte: u8) -> crate::Result<()>;
25    fn write_all(&mut self, bytes: &[u8]) -> crate::Result<()>;
26}
27
28#[allow(async_fn_in_trait)]
29pub trait AsyncEncoder: Unpin {
30    async fn write_u8(&mut self, byte: u8) -> crate::Result<()>;
31    async fn write_all(&mut self, bytes: &[u8]) -> crate::Result<()>;
32}
33
34// ---- Impls
35
36impl<T> Encode for [T]
37where
38    T: Encode,
39{
40    #[async_impl]
41    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
42        self.len().encode_async(writer).await?;
43
44        if type_eq::<T, u8>() {
45            let this = unsafe { transmute_slice(self) };
46            writer.write_all(this).await?;
47            return Ok(());
48        }
49
50        for v in self {
51            v.encode_async(writer).await?;
52        }
53        Ok(())
54    }
55
56    fn encode_size(&self) -> usize {
57        let usize_bytes = std::mem::size_of::<usize>();
58
59        if type_eq::<T, u8>() {
60            return usize_bytes + self.len();
61        }
62
63        usize_bytes + self.iter().map(|t| t.encode_size()).sum::<usize>()
64    }
65}
66
67impl<T> Encode for Vec<T>
68where
69    T: Encode,
70{
71    #[async_impl]
72    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
73        self.len().encode_async(writer).await?;
74
75        if type_eq::<T, u8>() {
76            let this = unsafe { transmute_slice(self) };
77            writer.write_all(this).await?;
78            return Ok(());
79        }
80
81        for v in self {
82            v.encode_async(writer).await?;
83        }
84        Ok(())
85    }
86
87    fn encode_size(&self) -> usize {
88        let usize_bytes = std::mem::size_of::<usize>();
89
90        if type_eq::<T, u8>() {
91            return usize_bytes + self.len();
92        }
93
94        usize_bytes + self.iter().map(|t| t.encode_size()).sum::<usize>()
95    }
96}
97
98impl Encode for bytes::Bytes {
99    #[async_impl]
100    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
101        self.as_ref().encode_async(writer).await
102    }
103
104    fn encode_size(&self) -> usize {
105        self.as_ref().encode_size()
106    }
107}
108
109impl<T, const N: usize> Encode for [T; N]
110where
111    T: Encode,
112{
113    #[async_impl]
114    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
115        if type_eq::<T, u8>() {
116            let this = unsafe { transmute_slice(self) };
117            writer.write_all(this).await?;
118            return Ok(());
119        }
120
121        for v in self {
122            v.encode_async(writer).await?;
123        }
124        Ok(())
125    }
126
127    fn encode_size(&self) -> usize {
128        if type_eq::<T, u8>() {
129            return self.len();
130        }
131
132        self.iter().map(|t| t.encode_size()).sum()
133    }
134}
135
136macro_rules! gen_nums {
137    ($($ty:ident),*) => {
138        $(
139            impl Encode for $ty {
140                #[async_impl]
141                async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
142                    writer.write_all(&self.to_ne_bytes()).await?;
143                    Ok(())
144                }
145
146                fn encode_size(&self) -> usize {
147                    std::mem::size_of::<$ty>()
148                }
149            }
150        )*
151    };
152}
153
154// Optimise for bytes
155impl Encode for u8 {
156    #[async_impl]
157    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
158        writer.write_u8(*self).await?;
159        Ok(())
160    }
161
162    fn encode_size(&self) -> usize {
163        1
164    }
165}
166impl Encode for i8 {
167    #[async_impl]
168    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
169        writer.write_u8(*self as u8).await?;
170        Ok(())
171    }
172
173    fn encode_size(&self) -> usize {
174        1
175    }
176}
177impl Encode for bool {
178    #[async_impl]
179    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
180        writer.write_u8(*self as u8).await?;
181        Ok(())
182    }
183
184    fn encode_size(&self) -> usize {
185        1
186    }
187}
188
189// Standadize across platforms (8bytes vs 4bytes) -> always use 8 bytes
190impl Encode for usize {
191    #[async_impl]
192    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
193        (*self as u64).encode_async(writer).await?;
194        Ok(())
195    }
196
197    fn encode_size(&self) -> usize {
198        std::mem::size_of::<u64>()
199    }
200}
201impl Encode for isize {
202    #[async_impl]
203    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
204        (*self as i64).encode_async(writer).await?;
205        Ok(())
206    }
207
208    fn encode_size(&self) -> usize {
209        std::mem::size_of::<i64>()
210    }
211}
212
213gen_nums!(u16, u32, u64, u128);
214gen_nums!(i16, i32, i64, i128);
215gen_nums!(f32, f64);
216
217impl Encode for &str {
218    #[async_impl]
219    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
220        let b = self.as_bytes();
221        b.encode_async(writer).await
222    }
223
224    fn encode_size(&self) -> usize {
225        self.as_bytes().encode_size()
226    }
227}
228
229impl Encode for String {
230    #[async_impl]
231    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
232        let b = self.as_bytes();
233        b.encode_async(writer).await
234    }
235
236    fn encode_size(&self) -> usize {
237        self.as_bytes().encode_size()
238    }
239}
240
241impl<T> Encode for std::marker::PhantomData<T> {
242    #[async_impl]
243    async fn encode_async(&self, _: &mut impl AsyncEncoder) -> crate::Result<()> {
244        Ok(())
245    }
246
247    fn encode_size(&self) -> usize {
248        0
249    }
250}
251
252impl<K, V> Encode for std::collections::HashMap<K, V>
253where
254    K: Encode,
255    V: Encode,
256{
257    #[async_impl]
258    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
259        self.len().encode_async(writer).await?;
260
261        for (k, v) in self {
262            k.encode_async(writer).await?;
263            v.encode_async(writer).await?;
264        }
265        Ok(())
266    }
267
268    fn encode_size(&self) -> usize {
269        std::mem::size_of::<usize>()
270            + self
271                .iter()
272                .map(|(k, v)| k.encode_size() + v.encode_size())
273                .sum::<usize>()
274    }
275}
276
277impl<K> Encode for std::collections::HashSet<K>
278where
279    K: Encode,
280{
281    #[async_impl]
282    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
283        self.len().encode_async(writer).await?;
284
285        for k in self {
286            k.encode_async(writer).await?;
287        }
288        Ok(())
289    }
290
291    fn encode_size(&self) -> usize {
292        std::mem::size_of::<usize>() + self.iter().map(|k| k.encode_size()).sum::<usize>()
293    }
294}
295
296impl<K, V> Encode for std::collections::BTreeMap<K, V>
297where
298    K: Encode,
299    V: Encode,
300{
301    #[async_impl]
302    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
303        self.len().encode_async(writer).await?;
304
305        for (k, v) in self {
306            k.encode_async(writer).await?;
307            v.encode_async(writer).await?;
308        }
309        Ok(())
310    }
311
312    fn encode_size(&self) -> usize {
313        std::mem::size_of::<usize>()
314            + self
315                .iter()
316                .map(|(k, v)| k.encode_size() + v.encode_size())
317                .sum::<usize>()
318    }
319}
320
321impl<K> Encode for std::collections::BTreeSet<K>
322where
323    K: Encode,
324{
325    #[async_impl]
326    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
327        self.len().encode_async(writer).await?;
328
329        for k in self {
330            k.encode_async(writer).await?;
331        }
332        Ok(())
333    }
334
335    fn encode_size(&self) -> usize {
336        std::mem::size_of::<usize>() + self.iter().map(|k| k.encode_size()).sum::<usize>()
337    }
338}
339
340impl<T> Encode for std::collections::VecDeque<T>
341where
342    T: Encode,
343{
344    #[async_impl]
345    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
346        self.len().encode_async(writer).await?;
347
348        if type_eq::<T, u8>() {
349            let (front, back) = self.as_slices();
350            let front = unsafe { transmute_slice(front) };
351            let back = unsafe { transmute_slice(back) };
352            writer.write_all(front).await?;
353            writer.write_all(back).await?;
354            return Ok(());
355        }
356
357        for v in self {
358            v.encode_async(writer).await?;
359        }
360        Ok(())
361    }
362
363    fn encode_size(&self) -> usize {
364        let usize_bytes = std::mem::size_of::<usize>();
365
366        if type_eq::<T, u8>() {
367            return usize_bytes + self.len();
368        }
369
370        usize_bytes + self.iter().map(|t| t.encode_size()).sum::<usize>()
371    }
372}
373
374impl<T> Encode for std::collections::LinkedList<T>
375where
376    T: Encode,
377{
378    #[async_impl]
379    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
380        self.len().encode_async(writer).await?;
381
382        for v in self {
383            v.encode_async(writer).await?;
384        }
385        Ok(())
386    }
387
388    fn encode_size(&self) -> usize {
389        let usize_bytes = std::mem::size_of::<usize>();
390
391        if type_eq::<T, u8>() {
392            return usize_bytes + self.len();
393        }
394
395        usize_bytes + self.iter().map(|t| t.encode_size()).sum::<usize>()
396    }
397}
398
399impl<T> Encode for std::collections::BinaryHeap<T>
400where
401    T: Encode,
402{
403    #[async_impl]
404    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
405        self.len().encode_async(writer).await?;
406
407        for v in self {
408            v.encode_async(writer).await?;
409        }
410        Ok(())
411    }
412
413    fn encode_size(&self) -> usize {
414        let usize_bytes = std::mem::size_of::<usize>();
415
416        if type_eq::<T, u8>() {
417            return usize_bytes + self.len();
418        }
419
420        usize_bytes + self.iter().map(|t| t.encode_size()).sum::<usize>()
421    }
422}
423
424impl<T> Encode for Box<T>
425where
426    T: Encode,
427{
428    #[async_impl]
429    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
430        self.as_ref().encode_async(writer).await
431    }
432
433    fn encode_size(&self) -> usize {
434        self.as_ref().encode_size()
435    }
436}
437
438impl<T, E> Encode for std::result::Result<T, E>
439where
440    T: Encode,
441    E: Encode,
442{
443    #[async_impl]
444    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
445        match self {
446            Ok(t) => {
447                writer.write_u8(0).await?;
448                t.encode_async(writer).await?;
449            }
450            Err(e) => {
451                writer.write_u8(1).await?;
452                e.encode_async(writer).await?;
453            }
454        }
455        Ok(())
456    }
457    fn encode_size(&self) -> usize {
458        1 + match self {
459            Ok(t) => t.encode_size(),
460            Err(e) => e.encode_size(),
461        }
462    }
463}
464
465impl<T> Encode for Option<T>
466where
467    T: Encode,
468{
469    #[async_impl]
470    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
471        match self {
472            None => {
473                writer.write_u8(0).await?;
474            }
475            Some(t) => {
476                writer.write_u8(1).await?;
477                t.encode_async(writer).await?;
478            }
479        }
480        Ok(())
481    }
482    fn encode_size(&self) -> usize {
483        1 + match self {
484            None => 0,
485            Some(t) => t.encode_size(),
486        }
487    }
488}
489
490impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> Encode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)
491where
492    T0: Encode,
493    T1: Encode,
494    T2: Encode,
495    T3: Encode,
496    T4: Encode,
497    T5: Encode,
498    T6: Encode,
499    T7: Encode,
500    T8: Encode,
501    T9: Encode,
502{
503    #[async_impl]
504    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
505        self.0.encode_async(writer).await?;
506        self.1.encode_async(writer).await?;
507        self.2.encode_async(writer).await?;
508        self.3.encode_async(writer).await?;
509        self.4.encode_async(writer).await?;
510        self.5.encode_async(writer).await?;
511        self.6.encode_async(writer).await?;
512        self.7.encode_async(writer).await?;
513        self.8.encode_async(writer).await?;
514        self.9.encode_async(writer).await?;
515        Ok(())
516    }
517
518    fn encode_size(&self) -> usize {
519        self.0.encode_size()
520            + self.1.encode_size()
521            + self.2.encode_size()
522            + self.3.encode_size()
523            + self.4.encode_size()
524            + self.5.encode_size()
525            + self.6.encode_size()
526            + self.7.encode_size()
527            + self.8.encode_size()
528            + self.9.encode_size()
529    }
530}
531
532impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> Encode for (T0, T1, T2, T3, T4, T5, T6, T7, T8)
533where
534    T0: Encode,
535    T1: Encode,
536    T2: Encode,
537    T3: Encode,
538    T4: Encode,
539    T5: Encode,
540    T6: Encode,
541    T7: Encode,
542    T8: Encode,
543{
544    #[async_impl]
545    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
546        self.0.encode_async(writer).await?;
547        self.1.encode_async(writer).await?;
548        self.2.encode_async(writer).await?;
549        self.3.encode_async(writer).await?;
550        self.4.encode_async(writer).await?;
551        self.5.encode_async(writer).await?;
552        self.6.encode_async(writer).await?;
553        self.7.encode_async(writer).await?;
554        self.8.encode_async(writer).await?;
555        Ok(())
556    }
557
558    fn encode_size(&self) -> usize {
559        self.0.encode_size()
560            + self.1.encode_size()
561            + self.2.encode_size()
562            + self.3.encode_size()
563            + self.4.encode_size()
564            + self.5.encode_size()
565            + self.6.encode_size()
566            + self.7.encode_size()
567            + self.8.encode_size()
568    }
569}
570
571impl<T0, T1, T2, T3, T4, T5, T6, T7> Encode for (T0, T1, T2, T3, T4, T5, T6, T7)
572where
573    T0: Encode,
574    T1: Encode,
575    T2: Encode,
576    T3: Encode,
577    T4: Encode,
578    T5: Encode,
579    T6: Encode,
580    T7: Encode,
581{
582    #[async_impl]
583    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
584        self.0.encode_async(writer).await?;
585        self.1.encode_async(writer).await?;
586        self.2.encode_async(writer).await?;
587        self.3.encode_async(writer).await?;
588        self.4.encode_async(writer).await?;
589        self.5.encode_async(writer).await?;
590        self.6.encode_async(writer).await?;
591        self.7.encode_async(writer).await?;
592        Ok(())
593    }
594
595    fn encode_size(&self) -> usize {
596        self.0.encode_size()
597            + self.1.encode_size()
598            + self.2.encode_size()
599            + self.3.encode_size()
600            + self.4.encode_size()
601            + self.5.encode_size()
602            + self.6.encode_size()
603            + self.7.encode_size()
604    }
605}
606
607impl<T0, T1, T2, T3, T4, T5, T6> Encode for (T0, T1, T2, T3, T4, T5, T6)
608where
609    T0: Encode,
610    T1: Encode,
611    T2: Encode,
612    T3: Encode,
613    T4: Encode,
614    T5: Encode,
615    T6: Encode,
616{
617    #[async_impl]
618    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
619        self.0.encode_async(writer).await?;
620        self.1.encode_async(writer).await?;
621        self.2.encode_async(writer).await?;
622        self.3.encode_async(writer).await?;
623        self.4.encode_async(writer).await?;
624        self.5.encode_async(writer).await?;
625        self.6.encode_async(writer).await?;
626        Ok(())
627    }
628
629    fn encode_size(&self) -> usize {
630        self.0.encode_size()
631            + self.1.encode_size()
632            + self.2.encode_size()
633            + self.3.encode_size()
634            + self.4.encode_size()
635            + self.5.encode_size()
636            + self.6.encode_size()
637    }
638}
639
640impl<T0, T1, T2, T3, T4, T5> Encode for (T0, T1, T2, T3, T4, T5)
641where
642    T0: Encode,
643    T1: Encode,
644    T2: Encode,
645    T3: Encode,
646    T4: Encode,
647    T5: Encode,
648{
649    #[async_impl]
650    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
651        self.0.encode_async(writer).await?;
652        self.1.encode_async(writer).await?;
653        self.2.encode_async(writer).await?;
654        self.3.encode_async(writer).await?;
655        self.4.encode_async(writer).await?;
656        self.5.encode_async(writer).await?;
657        Ok(())
658    }
659
660    fn encode_size(&self) -> usize {
661        self.0.encode_size()
662            + self.1.encode_size()
663            + self.2.encode_size()
664            + self.3.encode_size()
665            + self.4.encode_size()
666            + self.5.encode_size()
667    }
668}
669
670impl<T0, T1, T2, T3, T4> Encode for (T0, T1, T2, T3, T4)
671where
672    T0: Encode,
673    T1: Encode,
674    T2: Encode,
675    T3: Encode,
676    T4: Encode,
677{
678    #[async_impl]
679    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
680        self.0.encode_async(writer).await?;
681        self.1.encode_async(writer).await?;
682        self.2.encode_async(writer).await?;
683        self.3.encode_async(writer).await?;
684        self.4.encode_async(writer).await?;
685        Ok(())
686    }
687
688    fn encode_size(&self) -> usize {
689        self.0.encode_size()
690            + self.1.encode_size()
691            + self.2.encode_size()
692            + self.3.encode_size()
693            + self.4.encode_size()
694    }
695}
696
697impl<T0, T1, T2, T3> Encode for (T0, T1, T2, T3)
698where
699    T0: Encode,
700    T1: Encode,
701    T2: Encode,
702    T3: Encode,
703{
704    #[async_impl]
705    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
706        self.0.encode_async(writer).await?;
707        self.1.encode_async(writer).await?;
708        self.2.encode_async(writer).await?;
709        self.3.encode_async(writer).await?;
710        Ok(())
711    }
712
713    fn encode_size(&self) -> usize {
714        self.0.encode_size() + self.1.encode_size() + self.2.encode_size() + self.3.encode_size()
715    }
716}
717
718impl<T0, T1, T2> Encode for (T0, T1, T2)
719where
720    T0: Encode,
721    T1: Encode,
722    T2: Encode,
723{
724    #[async_impl]
725    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
726        self.0.encode_async(writer).await?;
727        self.1.encode_async(writer).await?;
728        self.2.encode_async(writer).await?;
729        Ok(())
730    }
731
732    fn encode_size(&self) -> usize {
733        self.0.encode_size() + self.1.encode_size() + self.2.encode_size()
734    }
735}
736
737impl<T0, T1> Encode for (T0, T1)
738where
739    T0: Encode,
740    T1: Encode,
741{
742    #[async_impl]
743    async fn encode_async(&self, writer: &mut impl AsyncEncoder) -> crate::Result<()> {
744        self.0.encode_async(writer).await?;
745        self.1.encode_async(writer).await?;
746        Ok(())
747    }
748
749    fn encode_size(&self) -> usize {
750        self.0.encode_size() + self.1.encode_size()
751    }
752}
753
754impl Encode for () {
755    #[async_impl]
756    async fn encode_async(&self, _: &mut impl AsyncEncoder) -> crate::Result<()> {
757        Ok(())
758    }
759    fn encode_size(&self) -> usize {
760        0
761    }
762}