musli/storage/
en.rs

1use core::fmt;
2use core::marker::PhantomData;
3use core::mem::size_of_val;
4use core::slice;
5
6use crate::en::{
7    utils, Encode, Encoder, EntriesEncoder, EntryEncoder, MapEncoder, SequenceEncoder,
8    TryFastEncode, VariantEncoder,
9};
10use crate::hint::{MapHint, SequenceHint};
11use crate::{Context, Options, Writer};
12
13use super::macros::is_bitwise_encode;
14
15/// A very simple encoder suitable for storage encoding.
16pub struct StorageEncoder<const OPT: Options, const PACK: bool, W, C, M>
17where
18    M: 'static,
19{
20    cx: C,
21    writer: W,
22    _marker: PhantomData<M>,
23}
24
25impl<const OPT: Options, const PACK: bool, W, C, M> StorageEncoder<OPT, PACK, W, C, M>
26where
27    M: 'static,
28{
29    /// Construct a new storage encoder.
30    #[inline]
31    pub(crate) fn new(cx: C, writer: W) -> Self {
32        Self {
33            cx,
34            writer,
35            _marker: PhantomData,
36        }
37    }
38}
39
40#[crate::encoder(crate)]
41impl<const OPT: Options, const PACK: bool, W, C, M> Encoder for StorageEncoder<OPT, PACK, W, C, M>
42where
43    W: Writer,
44    C: Context,
45    M: 'static,
46{
47    type Cx = C;
48    type Error = C::Error;
49    type Mode = M;
50    type EncodePack = StorageEncoder<OPT, true, W, C, M>;
51    type EncodeSome = Self;
52    type EncodeSequence = Self;
53    type EncodeMap = Self;
54    type EncodeMapEntries = Self;
55    type EncodeVariant = Self;
56    type EncodeSequenceVariant = Self;
57    type EncodeMapVariant = Self;
58
59    #[inline]
60    fn cx(&self) -> Self::Cx {
61        self.cx
62    }
63
64    #[inline]
65    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        write!(f, "type supported by the storage encoder")
67    }
68
69    #[inline]
70    fn try_fast_encode<T>(mut self, value: T) -> Result<TryFastEncode<T, Self>, Self::Error>
71    where
72        T: Encode<Self::Mode>,
73    {
74        if !is_bitwise_encode!(OPT, T::Encode) {
75            return Ok(TryFastEncode::Unsupported(value, self));
76        }
77
78        let value = value.as_encode();
79
80        // SAFETY: We've ensured the type is layout compatible with the current
81        // serialization just above.
82        let slice = unsafe {
83            let at = (value as *const T::Encode).cast::<u8>();
84            slice::from_raw_parts(at, size_of_val(value))
85        };
86
87        self.writer.write_bytes(self.cx, slice)?;
88        Ok(TryFastEncode::Ok)
89    }
90
91    #[inline]
92    fn encode_empty(self) -> Result<(), Self::Error> {
93        self.encode_sequence_fn(0, |_| Ok(()))
94    }
95
96    #[inline]
97    fn encode_pack(self) -> Result<Self::EncodePack, Self::Error> {
98        Ok(StorageEncoder::<OPT, true, _, _, M>::new(
99            self.cx,
100            self.writer,
101        ))
102    }
103
104    #[inline]
105    fn encode_array<const N: usize>(mut self, array: &[u8; N]) -> Result<(), Self::Error> {
106        self.writer.write_bytes(self.cx, array)
107    }
108
109    #[inline]
110    fn encode_bytes(mut self, bytes: &[u8]) -> Result<(), Self::Error> {
111        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), bytes.len())?;
112        self.writer.write_bytes(self.cx, bytes)?;
113        Ok(())
114    }
115
116    #[inline]
117    fn encode_bytes_vectored<I>(mut self, len: usize, vectors: I) -> Result<(), Self::Error>
118    where
119        I: IntoIterator<Item: AsRef<[u8]>>,
120    {
121        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?;
122
123        for bytes in vectors {
124            self.writer.write_bytes(self.cx, bytes.as_ref())?;
125        }
126
127        Ok(())
128    }
129
130    #[inline]
131    fn encode_string(mut self, string: &str) -> Result<(), Self::Error> {
132        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), string.len())?;
133        self.writer.write_bytes(self.cx, string.as_bytes())?;
134        Ok(())
135    }
136
137    #[inline]
138    fn encode_bool(mut self, value: bool) -> Result<(), Self::Error> {
139        self.writer.write_byte(self.cx, if value { 1 } else { 0 })
140    }
141
142    #[inline]
143    fn encode_char(self, value: char) -> Result<(), Self::Error> {
144        self.encode_u32(value as u32)
145    }
146
147    #[inline]
148    fn encode_u8(mut self, value: u8) -> Result<(), Self::Error> {
149        self.writer.write_byte(self.cx, value)
150    }
151
152    #[inline]
153    fn encode_u16(mut self, value: u16) -> Result<(), Self::Error> {
154        crate::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
155    }
156
157    #[inline]
158    fn encode_u32(mut self, value: u32) -> Result<(), Self::Error> {
159        crate::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
160    }
161
162    #[inline]
163    fn encode_u64(mut self, value: u64) -> Result<(), Self::Error> {
164        crate::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
165    }
166
167    #[inline]
168    fn encode_u128(mut self, value: u128) -> Result<(), Self::Error> {
169        crate::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
170    }
171
172    #[inline]
173    fn encode_i8(self, value: i8) -> Result<(), Self::Error> {
174        self.encode_u8(value as u8)
175    }
176
177    #[inline]
178    fn encode_i16(mut self, value: i16) -> Result<(), Self::Error> {
179        crate::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
180    }
181
182    #[inline]
183    fn encode_i32(mut self, value: i32) -> Result<(), Self::Error> {
184        crate::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
185    }
186
187    #[inline]
188    fn encode_i64(mut self, value: i64) -> Result<(), Self::Error> {
189        crate::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
190    }
191
192    #[inline]
193    fn encode_i128(mut self, value: i128) -> Result<(), Self::Error> {
194        crate::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value)
195    }
196
197    #[inline]
198    fn encode_f32(self, value: f32) -> Result<(), Self::Error> {
199        self.encode_u32(value.to_bits())
200    }
201
202    #[inline]
203    fn encode_f64(self, value: f64) -> Result<(), Self::Error> {
204        self.encode_u64(value.to_bits())
205    }
206
207    #[inline]
208    fn encode_usize(mut self, value: usize) -> Result<(), Self::Error> {
209        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), value)
210    }
211
212    #[inline]
213    fn encode_isize(self, value: isize) -> Result<(), Self::Error> {
214        self.encode_usize(value as usize)
215    }
216
217    #[inline]
218    fn encode_some(mut self) -> Result<Self::EncodeSome, Self::Error> {
219        if !PACK {
220            self.writer.write_byte(self.cx, 1)?;
221        }
222
223        Ok(self)
224    }
225
226    #[inline]
227    fn encode_none(mut self) -> Result<(), Self::Error> {
228        if !PACK {
229            self.writer.write_byte(self.cx, 0)?;
230        }
231
232        Ok(())
233    }
234
235    #[inline]
236    fn encode_slice<T>(mut self, slice: impl AsRef<[T]>) -> Result<(), Self::Error>
237    where
238        T: Encode<Self::Mode>,
239    {
240        // Check that the type is packed inside of the slice.
241        if !is_bitwise_encode!(OPT, [T]) {
242            return utils::default_encode_slice(self, slice);
243        }
244
245        // SAFETY: We've ensured the type is layout compatible with the current
246        // serialization just above.
247        unsafe { encode_packed_len_slice(self.writer.borrow_mut(), self.cx, slice) }
248    }
249
250    #[inline]
251    fn encode_slices<T>(
252        mut self,
253        len: usize,
254        slices: impl IntoIterator<Item: AsRef<[T]>>,
255    ) -> Result<(), Self::Error>
256    where
257        T: Encode<Self::Mode>,
258    {
259        // Check that the type is packed inside of the slice.
260        if !is_bitwise_encode!(OPT, [T]) {
261            return utils::default_encode_slices(self, len, slices);
262        }
263
264        // SAFETY: We've ensured the type is layout compatible with the current
265        // serialization just above.
266        unsafe { encode_packed_len_slices(self.writer.borrow_mut(), self.cx, len, slices) }
267    }
268
269    #[inline]
270    fn encode_sequence(
271        mut self,
272        hint: impl SequenceHint,
273    ) -> Result<Self::EncodeSequence, Self::Error> {
274        let size = hint.require(self.cx)?;
275        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), size)?;
276        Ok(self)
277    }
278
279    #[inline]
280    fn encode_map(mut self, hint: impl MapHint) -> Result<Self::EncodeMap, Self::Error> {
281        let size = hint.require(self.cx)?;
282        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), size)?;
283        Ok(self)
284    }
285
286    #[inline]
287    fn encode_map_entries(
288        mut self,
289        hint: impl MapHint,
290    ) -> Result<Self::EncodeMapEntries, Self::Error> {
291        let size = hint.require(self.cx)?;
292        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), size)?;
293        Ok(self)
294    }
295
296    #[inline]
297    fn encode_variant(self) -> Result<Self::EncodeVariant, Self::Error> {
298        Ok(self)
299    }
300
301    #[inline]
302    fn encode_sequence_variant<T>(
303        mut self,
304        tag: &T,
305        hint: impl SequenceHint,
306    ) -> Result<Self::EncodeSequenceVariant, Self::Error>
307    where
308        T: ?Sized + Encode<Self::Mode>,
309    {
310        let size = hint.require(self.cx)?;
311        StorageEncoder::<OPT, PACK, _, _, M>::new(self.cx, self.writer.borrow_mut()).encode(tag)?;
312        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), size)?;
313        Ok(self)
314    }
315
316    #[inline]
317    fn encode_map_variant<T>(
318        mut self,
319        tag: &T,
320        hint: impl MapHint,
321    ) -> Result<Self::EncodeMapVariant, Self::Error>
322    where
323        T: ?Sized + Encode<Self::Mode>,
324    {
325        let size = hint.require(self.cx)?;
326        StorageEncoder::<OPT, PACK, _, _, M>::new(self.cx, self.writer.borrow_mut()).encode(tag)?;
327        crate::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), size)?;
328        Ok(self)
329    }
330}
331
332impl<const OPT: Options, const PACK: bool, W, C, M> SequenceEncoder
333    for StorageEncoder<OPT, PACK, W, C, M>
334where
335    W: Writer,
336    C: Context,
337    M: 'static,
338{
339    type Cx = C;
340    type Error = C::Error;
341    type Mode = M;
342    type EncodeNext<'this>
343        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
344    where
345        Self: 'this;
346
347    #[inline]
348    fn cx(&self) -> Self::Cx {
349        self.cx
350    }
351
352    #[inline]
353    fn encode_next(&mut self) -> Result<Self::EncodeNext<'_>, Self::Error> {
354        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
355    }
356
357    #[inline]
358    fn encode_slice<T>(&mut self, slice: impl AsRef<[T]>) -> Result<(), Self::Error>
359    where
360        T: Encode<Self::Mode>,
361    {
362        // Check that the type is packed inside of the slice.
363        if !is_bitwise_encode!(OPT, [T]) {
364            return utils::default_sequence_encode_slice(self, slice);
365        }
366
367        // SAFETY: We've ensured the type is layout compatible with the current
368        // serialization just above.
369        unsafe { encode_packed_slice(self.writer.borrow_mut(), self.cx, slice) }
370    }
371
372    #[inline]
373    fn encode_slices<T>(
374        &mut self,
375        slices: impl IntoIterator<Item: AsRef<[T]>>,
376    ) -> Result<(), Self::Error>
377    where
378        T: Encode<Self::Mode>,
379    {
380        // Check that the type is packed inside of the slice.
381        if !is_bitwise_encode!(OPT, [T]) {
382            return utils::default_sequence_encode_slices(self, slices);
383        }
384
385        // SAFETY: We've ensured the type is layout compatible with the current
386        // serialization just above.
387        unsafe { encode_packed_slices(self.writer.borrow_mut(), self.cx, slices) }
388    }
389
390    #[inline]
391    fn finish_sequence(self) -> Result<(), Self::Error> {
392        Ok(())
393    }
394}
395
396impl<const OPT: Options, const PACK: bool, W, C, M> MapEncoder
397    for StorageEncoder<OPT, PACK, W, C, M>
398where
399    W: Writer,
400    C: Context,
401    M: 'static,
402{
403    type Cx = C;
404    type Error = C::Error;
405    type Mode = M;
406    type EncodeEntry<'this>
407        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
408    where
409        Self: 'this;
410
411    #[inline]
412    fn cx(&self) -> Self::Cx {
413        self.cx
414    }
415
416    #[inline]
417    fn encode_entry(&mut self) -> Result<Self::EncodeEntry<'_>, Self::Error> {
418        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
419    }
420
421    #[inline]
422    fn finish_map(self) -> Result<(), Self::Error> {
423        Ok(())
424    }
425}
426
427impl<const OPT: Options, const PACK: bool, W, C, M> EntryEncoder
428    for StorageEncoder<OPT, PACK, W, C, M>
429where
430    W: Writer,
431    C: Context,
432    M: 'static,
433{
434    type Cx = C;
435    type Error = C::Error;
436    type Mode = M;
437    type EncodeKey<'this>
438        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
439    where
440        Self: 'this;
441    type EncodeValue<'this>
442        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
443    where
444        Self: 'this;
445
446    #[inline]
447    fn cx(&self) -> Self::Cx {
448        self.cx
449    }
450
451    #[inline]
452    fn encode_key(&mut self) -> Result<Self::EncodeKey<'_>, Self::Error> {
453        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
454    }
455
456    #[inline]
457    fn encode_value(&mut self) -> Result<Self::EncodeValue<'_>, Self::Error> {
458        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
459    }
460
461    #[inline]
462    fn finish_entry(self) -> Result<(), Self::Error> {
463        Ok(())
464    }
465}
466
467impl<const OPT: Options, const PACK: bool, W, C, M> EntriesEncoder
468    for StorageEncoder<OPT, PACK, W, C, M>
469where
470    W: Writer,
471    C: Context,
472    M: 'static,
473{
474    type Cx = C;
475    type Error = C::Error;
476    type Mode = M;
477    type EncodeEntryKey<'this>
478        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
479    where
480        Self: 'this;
481    type EncodeEntryValue<'this>
482        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
483    where
484        Self: 'this;
485
486    #[inline]
487    fn cx(&self) -> Self::Cx {
488        self.cx
489    }
490
491    #[inline]
492    fn encode_entry_key(&mut self) -> Result<Self::EncodeEntryKey<'_>, Self::Error> {
493        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
494    }
495
496    #[inline]
497    fn encode_entry_value(&mut self) -> Result<Self::EncodeEntryValue<'_>, Self::Error> {
498        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
499    }
500
501    #[inline]
502    fn finish_entries(self) -> Result<(), Self::Error> {
503        Ok(())
504    }
505}
506
507impl<const OPT: Options, const PACK: bool, W, C, M> VariantEncoder
508    for StorageEncoder<OPT, PACK, W, C, M>
509where
510    W: Writer,
511    C: Context,
512    M: 'static,
513{
514    type Cx = C;
515    type Error = C::Error;
516    type Mode = M;
517    type EncodeTag<'this>
518        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
519    where
520        Self: 'this;
521    type EncodeData<'this>
522        = StorageEncoder<OPT, PACK, W::Mut<'this>, C, M>
523    where
524        Self: 'this;
525
526    #[inline]
527    fn cx(&self) -> Self::Cx {
528        self.cx
529    }
530
531    #[inline]
532    fn encode_tag(&mut self) -> Result<Self::EncodeTag<'_>, Self::Error> {
533        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
534    }
535
536    #[inline]
537    fn encode_data(&mut self) -> Result<Self::EncodeData<'_>, Self::Error> {
538        Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut()))
539    }
540
541    #[inline]
542    fn finish_variant(self) -> Result<(), Self::Error> {
543        Ok(())
544    }
545}
546
547/// Encode a packed length-prefixed slice.
548///
549/// # Safety
550///
551/// The caller must ensure that the format in use is compatible with the native
552/// format of the slice.
553#[inline]
554unsafe fn encode_packed_len_slice<W, C, T, M>(
555    mut writer: W,
556    cx: C,
557    slice: impl AsRef<[T]>,
558) -> Result<(), C::Error>
559where
560    W: Writer,
561    C: Context,
562    T: Encode<M>,
563{
564    let slice = slice.as_ref();
565    let len = slice.len().to_ne_bytes();
566    writer.write_bytes(cx, &len)?;
567
568    if size_of::<T>() > 0 {
569        let slice = {
570            let at = slice.as_ptr().cast::<u8>();
571            let size = size_of_val(slice);
572            slice::from_raw_parts(at, size)
573        };
574
575        writer.write_bytes(cx, slice)?;
576    }
577
578    Ok(())
579}
580
581/// Encode a packed length-prefixed slice from an iterator of slices.
582///
583/// # Safety
584///
585/// The caller must ensure that the format in use is compatible with the native
586/// format of the slice.
587#[inline]
588unsafe fn encode_packed_len_slices<W, C, I, T, M>(
589    mut writer: W,
590    cx: C,
591    len: usize,
592    slices: I,
593) -> Result<(), C::Error>
594where
595    W: Writer,
596    C: Context,
597    I: IntoIterator<Item: AsRef<[T]>>,
598    T: Encode<M>,
599{
600    let len = len.to_ne_bytes();
601    writer.write_bytes(cx, &len)?;
602
603    if size_of::<T>() > 0 {
604        for slice in slices {
605            let slice = slice.as_ref();
606
607            let slice = {
608                let at = slice.as_ptr().cast::<u8>();
609                let size = size_of_val(slice);
610                slice::from_raw_parts(at, size)
611            };
612
613            writer.write_bytes(cx, slice)?;
614        }
615    }
616
617    Ok(())
618}
619
620/// Encode a packed slice.
621///
622/// # Safety
623///
624/// The caller must ensure that the format in use is compatible with the native
625/// format of the slice.
626#[inline]
627unsafe fn encode_packed_slice<W, C, T, M>(
628    mut writer: W,
629    cx: C,
630    slice: impl AsRef<[T]>,
631) -> Result<(), C::Error>
632where
633    W: Writer,
634    C: Context,
635    T: Encode<M>,
636{
637    if size_of::<T>() > 0 {
638        let slice = slice.as_ref();
639
640        let slice = {
641            let at = slice.as_ptr().cast::<u8>();
642            let size = size_of_val(slice);
643            slice::from_raw_parts(at, size)
644        };
645
646        writer.write_bytes(cx, slice)?;
647    }
648
649    Ok(())
650}
651
652/// Encode a packed slice from an iterator of slices.
653///
654/// # Safety
655///
656/// The caller must ensure that the format in use is compatible with the native
657/// format of the slice.
658#[inline]
659unsafe fn encode_packed_slices<W, C, I, T, M>(
660    mut writer: W,
661    cx: C,
662    slices: I,
663) -> Result<(), C::Error>
664where
665    W: Writer,
666    C: Context,
667    I: IntoIterator<Item: AsRef<[T]>>,
668    T: Encode<M>,
669{
670    if size_of::<T>() > 0 {
671        for slice in slices {
672            let slice = slice.as_ref();
673
674            let slice = {
675                let at = slice.as_ptr().cast::<u8>();
676                let size = size_of_val(slice);
677                slice::from_raw_parts(at, size)
678            };
679
680            writer.write_bytes(cx, slice)?;
681        }
682    }
683
684    Ok(())
685}