From 25a267ccccbcf1e08a6c73542386456b51d95ced Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Sun, 24 Mar 2024 19:16:11 +0100 Subject: [PATCH] Rework decoding to be less error prone --- crates/musli-common/src/int/encoding.rs | 48 +- crates/musli-common/src/options.rs | 23 +- crates/musli-descriptive/src/de.rs | 451 ++++++++------- crates/musli-descriptive/src/en.rs | 132 +++-- crates/musli-descriptive/src/encoding.rs | 14 +- crates/musli-descriptive/src/test.rs | 2 +- crates/musli-json/src/de/key_decoder.rs | 12 +- crates/musli-json/src/de/mod.rs | 165 +++--- crates/musli-json/src/de/object_decoder.rs | 163 +++--- .../musli-json/src/de/object_pair_decoder.rs | 15 +- crates/musli-json/src/de/sequence_decoder.rs | 141 ++--- crates/musli-json/src/de/variant_decoder.rs | 33 +- crates/musli-json/src/en/array_encoder.rs | 52 +- crates/musli-json/src/en/mod.rs | 2 +- crates/musli-json/src/en/object_encoder.rs | 18 +- .../musli-json/src/en/object_pair_encoder.rs | 6 +- crates/musli-json/src/en/variant_encoder.rs | 2 +- crates/musli-json/src/parser/token.rs | 6 - crates/musli-macros/src/de.rs | 10 +- crates/musli-macros/src/en.rs | 12 +- crates/musli-macros/src/internals/tokens.rs | 14 +- crates/musli-macros/src/lib.rs | 50 -- crates/musli-macros/src/types.rs | 6 +- crates/musli-serde/src/deserializer.rs | 73 +-- crates/musli-serde/src/serializer.rs | 68 ++- crates/musli-storage/src/de.rs | 314 ++++++----- crates/musli-storage/src/en.rs | 165 +++--- crates/musli-storage/src/encoding.rs | 14 +- crates/musli-value/src/de.rs | 248 +++++---- crates/musli-value/src/en.rs | 116 +++- crates/musli-value/src/value.rs | 27 +- crates/musli-wire/src/de.rs | 524 ++++++++++-------- crates/musli-wire/src/en.rs | 156 +++--- crates/musli-wire/src/encoding.rs | 16 +- crates/musli-wire/src/test.rs | 2 +- crates/musli-wire/src/wire_int.rs | 36 +- crates/musli/src/compat.rs | 2 +- crates/musli/src/de/decoder.rs | 459 ++++----------- crates/musli/src/de/map_decoder.rs | 47 +- crates/musli/src/de/map_entries_decoder.rs | 17 +- crates/musli/src/de/mod.rs | 3 + crates/musli/src/de/pack_decoder.rs | 5 - crates/musli/src/de/sequence_decoder.rs | 12 - crates/musli/src/de/struct_decoder.rs | 44 +- crates/musli/src/de/struct_fields_decoder.rs | 2 +- crates/musli/src/de/tuple_decoder.rs | 32 ++ crates/musli/src/de/variant_decoder.rs | 3 - crates/musli/src/de/visitor.rs | 10 +- crates/musli/src/en/encoder.rs | 150 ++--- crates/musli/src/en/map_encoder.rs | 10 +- crates/musli/src/en/map_entries_encoder.rs | 4 +- crates/musli/src/en/map_entry_encoder.rs | 4 +- crates/musli/src/en/mod.rs | 6 + crates/musli/src/en/pack_encoder.rs | 37 ++ crates/musli/src/en/sequence_encoder.rs | 8 +- crates/musli/src/en/struct_encoder.rs | 24 +- crates/musli/src/en/struct_field_encoder.rs | 4 +- crates/musli/src/en/tuple_encoder.rs | 39 ++ crates/musli/src/en/variant_encoder.rs | 5 +- crates/musli/src/expecting.rs | 1 + crates/musli/src/impls/alloc.rs | 155 +++--- crates/musli/src/impls/mod.rs | 50 +- crates/musli/src/impls/net.rs | 38 +- crates/musli/src/impls/range.rs | 6 +- crates/musli/src/impls/tuples.rs | 36 +- crates/musli/src/lib.rs | 42 +- crates/musli/src/never.rs | 123 ++-- 67 files changed, 2305 insertions(+), 2209 deletions(-) create mode 100644 crates/musli/src/de/tuple_decoder.rs create mode 100644 crates/musli/src/en/pack_encoder.rs create mode 100644 crates/musli/src/en/tuple_encoder.rs diff --git a/crates/musli-common/src/int/encoding.rs b/crates/musli-common/src/int/encoding.rs index 41aa9ae57..001c1dc78 100644 --- a/crates/musli-common/src/int/encoding.rs +++ b/crates/musli-common/src/int/encoding.rs @@ -9,7 +9,7 @@ use crate::writer::Writer; /// Governs how unsigned integers are encoded into a [Writer]. #[inline] -pub fn encode_unsigned( +pub fn encode_unsigned( cx: &C, writer: W, value: T, @@ -19,10 +19,10 @@ where W: Writer, T: Unsigned + UnsignedOps, { - match crate::options::integer::() { + match crate::options::integer::() { crate::options::Integer::Variable => c::encode(cx, writer, value), _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); value.write_bytes(cx, writer, bo) } } @@ -31,7 +31,7 @@ where /// Decode an unsigned value from the specified reader using the configuration /// passed in through `F`. #[inline] -pub fn decode_unsigned<'de, C, R, T: UnsignedOps, const F: Options>( +pub fn decode_unsigned<'de, C, R, T: UnsignedOps, const OPT: Options>( cx: &C, reader: R, ) -> Result @@ -40,10 +40,10 @@ where R: Reader<'de>, T: Unsigned, { - match crate::options::integer::() { + match crate::options::integer::() { crate::options::Integer::Variable => c::decode(cx, reader), _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); T::read_bytes(cx, reader, bo) } } @@ -51,17 +51,21 @@ where /// Governs how signed integers are encoded into a [Writer]. #[inline] -pub fn encode_signed(cx: &C, writer: W, value: T) -> Result<(), C::Error> +pub fn encode_signed( + cx: &C, + writer: W, + value: T, +) -> Result<(), C::Error> where C: ?Sized + Context, W: Writer, T: Signed, T::Unsigned: UnsignedOps, { - match crate::options::integer::() { + match crate::options::integer::() { crate::options::Integer::Variable => c::encode(cx, writer, zig::encode(value)), _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); value.unsigned().write_bytes(cx, writer, bo) } } @@ -69,20 +73,20 @@ where /// Governs how signed integers are decoded from a [Reader]. #[inline] -pub fn decode_signed<'de, C, R, T, const F: Options>(cx: &C, reader: R) -> Result +pub fn decode_signed<'de, C, R, T, const OPT: Options>(cx: &C, reader: R) -> Result where C: ?Sized + Context, R: Reader<'de>, T: Signed, T::Unsigned: UnsignedOps, { - match crate::options::integer::() { + match crate::options::integer::() { crate::options::Integer::Variable => { let value: T::Unsigned = c::decode(cx, reader)?; Ok(zig::decode(value)) } _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); Ok(T::Unsigned::read_bytes(cx, reader, bo)?.signed()) } } @@ -90,15 +94,19 @@ where /// Governs how usize lengths are encoded into a [Writer]. #[inline] -pub fn encode_usize(cx: &C, writer: W, value: usize) -> Result<(), C::Error> +pub fn encode_usize( + cx: &C, + writer: W, + value: usize, +) -> Result<(), C::Error> where C: ?Sized + Context, W: Writer, { - match crate::options::length::() { + match crate::options::length::() { crate::options::Integer::Variable => c::encode(cx, writer, value), _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); macro_rules! fixed { ($ty:ty) => {{ let Ok(value) = <$ty>::try_from(value) else { @@ -109,22 +117,22 @@ where }}; } - crate::width_arm!(crate::options::length_width::(), fixed) + crate::width_arm!(crate::options::length_width::(), fixed) } } } /// Governs how usize lengths are decoded from a [Reader]. #[inline] -pub fn decode_usize<'de, C, R, const F: Options>(cx: &C, reader: R) -> Result +pub fn decode_usize<'de, C, R, const OPT: Options>(cx: &C, reader: R) -> Result where C: ?Sized + Context, R: Reader<'de>, { - match crate::options::length::() { + match crate::options::length::() { crate::options::Integer::Variable => c::decode(cx, reader), _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); macro_rules! fixed { ($ty:ty) => {{ @@ -138,7 +146,7 @@ where }}; } - crate::width_arm!(crate::options::length_width::(), fixed) + crate::width_arm!(crate::options::length_width::(), fixed) } } } diff --git a/crates/musli-common/src/options.rs b/crates/musli-common/src/options.rs index 86999a22a..cd97c29bf 100644 --- a/crates/musli-common/src/options.rs +++ b/crates/musli-common/src/options.rs @@ -14,6 +14,9 @@ pub const fn new() -> OptionsBuilder { /// /// Note: despite being made up of a primitive type, this cannot be serialized /// and correctly re-used. +/// +/// Making assumptions about its layout might lead to unspecified behavior +/// during encoding. Only use this type through the provided API. pub type Options = u128; const BYTEORDER_BIT: Options = 0; @@ -56,16 +59,16 @@ impl OptionsBuilder { } #[doc(hidden)] -pub const fn integer() -> Integer { - match (F >> INTEGER_BIT) & 0b1 { +pub const fn integer() -> Integer { + match (OPT >> INTEGER_BIT) & 0b1 { 0 => Integer::Variable, _ => Integer::Fixed, } } #[doc(hidden)] -pub const fn float() -> Float { - match (F >> FLOAT_BIT) & 0b11 { +pub const fn float() -> Float { + match (OPT >> FLOAT_BIT) & 0b11 { 0 => Float::Integer, 1 => Float::Variable, _ => Float::Fixed, @@ -73,16 +76,16 @@ pub const fn float() -> Float { } #[doc(hidden)] -pub const fn length() -> Integer { - match (F >> LENGTH_BIT) & 0b1 { +pub const fn length() -> Integer { + match (OPT >> LENGTH_BIT) & 0b1 { 0 => Integer::Variable, _ => Integer::Fixed, } } #[doc(hidden)] -pub const fn length_width() -> Width { - match (F >> LENGTH_WIDTH_BIT) & 0b11 { +pub const fn length_width() -> Width { + match (OPT >> LENGTH_WIDTH_BIT) & 0b11 { 0 => Width::U8, 1 => Width::U16, 2 => Width::U32, @@ -91,8 +94,8 @@ pub const fn length_width() -> Width { } #[doc(hidden)] -pub const fn byteorder() -> ByteOrder { - match (F >> BYTEORDER_BIT) & 0b1 { +pub const fn byteorder() -> ByteOrder { + match (OPT >> BYTEORDER_BIT) & 0b1 { 0 => ByteOrder::LittleEndian, _ => ByteOrder::BigEndian, } diff --git a/crates/musli-descriptive/src/de.rs b/crates/musli-descriptive/src/de.rs index 2620041f6..c29a2a4c0 100644 --- a/crates/musli-descriptive/src/de.rs +++ b/crates/musli-descriptive/src/de.rs @@ -1,4 +1,5 @@ use core::fmt; +use core::mem::take; #[cfg(feature = "alloc")] use alloc::vec::Vec; @@ -6,7 +7,7 @@ use alloc::vec::Vec; use musli::de::{ Decode, Decoder, MapDecoder, MapEntriesDecoder, MapEntryDecoder, NumberHint, NumberVisitor, PackDecoder, SequenceDecoder, SizeHint, StructDecoder, StructFieldDecoder, StructFieldsDecoder, - TypeHint, ValueVisitor, VariantDecoder, Visitor, + TupleDecoder, TypeHint, ValueVisitor, VariantDecoder, Visitor, }; use musli::Context; use musli_common::int::continuation as c; @@ -21,12 +22,12 @@ use crate::tag::{Kind, Mark, Tag, F32, F64, I128, I16, I32, I64, I8, U128, U16, const BUFFER_OPTIONS: crate::options::Options = crate::options::new().build(); /// A very simple decoder. -pub struct SelfDecoder<'a, R, const F: Options, C: ?Sized> { +pub struct SelfDecoder<'a, R, const OPT: Options, C: ?Sized> { cx: &'a C, reader: R, } -impl<'a, R, const F: Options, C: ?Sized> SelfDecoder<'a, R, F, C> { +impl<'a, R, const OPT: Options, C: ?Sized> SelfDecoder<'a, R, OPT, C> { /// Construct a new fixed width message encoder. #[inline] pub(crate) fn new(cx: &'a C, reader: R) -> Self { @@ -34,77 +35,105 @@ impl<'a, R, const F: Options, C: ?Sized> SelfDecoder<'a, R, F, C> { } } -pub struct SelfTupleDecoder<'a, R, const F: Options, C: ?Sized> { +impl<'a, 'de, R, const OPT: Options, C> SelfDecoder<'a, Limit, OPT, C> +where + R: Reader<'de>, + C: ?Sized + Context, +{ + #[inline] + fn end(mut self) -> Result<(), C::Error> { + if self.reader.remaining() > 0 { + self.reader.skip(self.cx, self.reader.remaining())?; + } + + Ok(()) + } +} + +pub struct SelfTupleDecoder<'a, R, const OPT: Options, C: ?Sized> { cx: &'a C, reader: R, } -impl<'a, R, const F: Options, C: ?Sized> SelfTupleDecoder<'a, R, F, C> { +impl<'a, R, const OPT: Options, C: ?Sized> SelfTupleDecoder<'a, R, OPT, C> { #[inline] pub(crate) fn new(cx: &'a C, reader: R) -> Self { Self { cx, reader } } } -impl<'a, 'de, R, const F: Options, C> SelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> SelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { /// Skip over any sequences of values. - pub(crate) fn skip_any(&mut self) -> Result<(), C::Error> { - let tag = Tag::from_byte(self.reader.read_byte(self.cx)?); + pub(crate) fn skip_any(mut self) -> Result<(), C::Error> { + let mut remaining = 1; - match tag.kind() { - Kind::Number => { - if tag.data().is_none() { - let _ = c::decode::<_, _, u128>(self.cx, self.reader.borrow_mut())?; - } - } - Kind::Mark => { - if let Mark::Variant = tag.mark() { - self.skip_any()?; - self.skip_any()?; - } - } - Kind::Bytes => { - let len = if let Some(len) = tag.data() { - len as usize - } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? - }; + while remaining > 0 { + remaining -= 1; - self.reader.skip(self.cx, len)?; - } - Kind::Pack => { - let len = 2usize.pow(tag.data_raw() as u32); - self.reader.skip(self.cx, len)?; - } - Kind::Sequence => { - let len = if let Some(len) = tag.data() { - len as usize - } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? - }; + let tag = Tag::from_byte(self.reader.read_byte(self.cx)?); - for _ in 0..len { - self.skip_any()?; + match tag.kind() { + Kind::Number => { + if tag.data().is_none() { + _ = c::decode::<_, _, u128>(self.cx, self.reader.borrow_mut())?; + } } - } - Kind::Map => { - let len = if let Some(len) = tag.data() { - len as usize - } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? - }; - - for _ in 0..len { - self.skip_any()?; - self.skip_any()?; + Kind::Mark => match tag.mark() { + Mark::Variant => { + remaining += 2; + } + Mark::Char => { + _ = c::decode::<_, _, u32>(self.cx, self.reader.borrow_mut())?; + } + _ => {} + }, + Kind::Bytes => { + let len = if let Some(len) = tag.data() { + len as usize + } else { + musli_common::int::decode_usize::<_, _, OPT>( + self.cx, + self.reader.borrow_mut(), + )? + }; + + self.reader.skip(self.cx, len)?; + } + Kind::Pack => { + let len = 2usize.pow(tag.data_raw() as u32); + self.reader.skip(self.cx, len)?; + } + Kind::Sequence => { + let len = if let Some(len) = tag.data() { + len as usize + } else { + musli_common::int::decode_usize::<_, _, OPT>( + self.cx, + self.reader.borrow_mut(), + )? + }; + + remaining += len; + } + Kind::Map => { + let len = if let Some(len) = tag.data() { + len as usize + } else { + musli_common::int::decode_usize::<_, _, OPT>( + self.cx, + self.reader.borrow_mut(), + )? + }; + + remaining += len * 2; + } + kind => { + return Err(self.cx.message(format_args!("Unsupported kind {kind:?}"))); } - } - kind => { - return Err(self.cx.message(format_args!("Unsupported kind {kind:?}"))); } } @@ -113,18 +142,18 @@ where // Standard function for decoding a pair sequence. #[inline] - fn shared_decode_map(mut self) -> Result, C::Error> { + fn shared_decode_map(mut self) -> Result, C::Error> { let pos = self.cx.mark(); let len = self.decode_prefix(Kind::Map, pos)?; - Ok(RemainingSelfDecoder::new(len, self)) + Ok(RemainingSelfDecoder::new(self.cx, self.reader, len)) } // Standard function for decoding a pair sequence. #[inline] - fn shared_decode_sequence(mut self) -> Result, C::Error> { + fn shared_decode_sequence(mut self) -> Result, C::Error> { let pos = self.cx.mark(); let len = self.decode_prefix(Kind::Sequence, pos)?; - Ok(RemainingSelfDecoder::new(len, self)) + Ok(RemainingSelfDecoder::new(self.cx, self.reader, len)) } /// Decode the length of a prefix. @@ -145,7 +174,7 @@ where Ok(if let Some(len) = tag.data() { len as usize } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? + musli_common::int::decode_usize::<_, _, OPT>(self.cx, self.reader.borrow_mut())? }) } @@ -158,7 +187,7 @@ where Kind::Bytes => Ok(if let Some(len) = tag.data() { len as usize } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? + musli_common::int::decode_usize::<_, _, OPT>(self.cx, self.reader.borrow_mut())? }), Kind::Pack => { let Some(len) = 2usize.checked_pow(tag.data_raw() as u32) else { @@ -177,13 +206,52 @@ where /// This simplifies implementing decoders that do not have any special handling /// for length-prefixed types. #[doc(hidden)] -pub struct RemainingSelfDecoder<'a, R, const F: Options, C: ?Sized> { +pub struct RemainingSelfDecoder<'a, R, const OPT: Options, C: ?Sized> { + cx: &'a C, + reader: R, remaining: usize, - decoder: SelfDecoder<'a, R, F, C>, +} + +impl<'a, 'de, R, const OPT: Options, C> RemainingSelfDecoder<'a, R, OPT, C> +where + R: Reader<'de>, + C: ?Sized + Context, +{ + #[inline] + fn new(cx: &'a C, reader: R, remaining: usize) -> Self { + Self { + cx, + reader, + remaining, + } + } + + #[inline] + fn skip_sequence_remaining(mut self) -> Result<(), C::Error> { + if let Some(item) = self.decode_next()? { + item.skip()?; + } + + Ok(()) + } + + #[inline] + fn skip_map_remaining(mut self) -> Result<(), C::Error> { + loop { + let Some(key) = self.decode_map_entry_key()? else { + break; + }; + + key.skip()?; + self.skip_map_entry_value()?; + } + + Ok(()) + } } #[musli::decoder] -impl<'a, 'de, R, const F: Options, C> Decoder<'de> for SelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> Decoder<'de> for SelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, @@ -191,15 +259,17 @@ where type Cx = C; type Error = C::Error; type Mode = C::Mode; - type WithContext<'this, U> = SelfDecoder<'this, R, F, U> where U: 'this + Context; + type WithContext<'this, U> = SelfDecoder<'this, R, OPT, U> where U: 'this + Context; #[cfg(feature = "musli-value")] type DecodeBuffer = musli_value::AsValueDecoder<'a, BUFFER_OPTIONS, C>; - type DecodePack = SelfDecoder<'a, Limit, F, C>; + type DecodePack = SelfDecoder<'a, Limit, OPT, C>; type DecodeSome = Self; - type DecodeSequence = RemainingSelfDecoder<'a, R, F, C>; - type DecodeTuple = SelfTupleDecoder<'a, R, F, C>; - type DecodeMap = RemainingSelfDecoder<'a, R, F, C>; - type DecodeStruct = RemainingSelfDecoder<'a, R, F, C>; + type DecodeSequence = RemainingSelfDecoder<'a, R, OPT, C>; + type DecodeTuple = SelfTupleDecoder<'a, R, OPT, C>; + type DecodeMap = RemainingSelfDecoder<'a, R, OPT, C>; + type DecodeMapEntries = RemainingSelfDecoder<'a, R, OPT, C>; + type DecodeStruct = RemainingSelfDecoder<'a, R, OPT, C>; + type DecodeStructFields = RemainingSelfDecoder<'a, R, OPT, C>; type DecodeVariant = Self; #[inline] @@ -229,7 +299,7 @@ where } #[inline] - fn skip(mut self) -> Result<(), C::Error> { + fn skip(self) -> Result<(), C::Error> { self.skip_any() } @@ -305,16 +375,21 @@ where } #[inline] - fn decode_unit(mut self) -> Result<(), C::Error> { - self.skip_any()?; - Ok(()) + fn decode_unit(self) -> Result<(), C::Error> { + self.skip() } #[inline] - fn decode_pack(mut self) -> Result { + fn decode_pack(mut self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodePack) -> Result, + { let pos = self.cx.mark(); let len = self.decode_pack_length(pos)?; - Ok(SelfDecoder::new(self.cx, self.reader.limit(len))) + let mut decoder = SelfDecoder::new(self.cx, self.reader.limit(len)); + let output = f(&mut decoder)?; + decoder.end()?; + Ok(output) } #[inline] @@ -591,12 +666,21 @@ where } #[inline] - fn decode_sequence(self) -> Result { - self.shared_decode_sequence() + fn decode_sequence(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeSequence) -> Result, + { + let mut decoder = self.shared_decode_sequence()?; + let output = f(&mut decoder)?; + decoder.skip_sequence_remaining()?; + Ok(output) } #[inline] - fn decode_tuple(mut self, len: usize) -> Result { + fn decode_tuple(mut self, len: usize, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeTuple) -> Result, + { let pos = self.cx.mark(); let actual = self.decode_prefix(Kind::Sequence, pos)?; @@ -606,21 +690,48 @@ where ))); } - Ok(SelfTupleDecoder::new(self.cx, self.reader)) + let mut decoder = SelfTupleDecoder::new(self.cx, self.reader); + let output = f(&mut decoder)?; + Ok(output) } #[inline] - fn decode_map(self) -> Result { + fn decode_map(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeMap) -> Result, + { + let mut decoder = self.shared_decode_map()?; + let output = f(&mut decoder)?; + decoder.skip_map_remaining()?; + Ok(output) + } + + #[inline] + fn decode_map_entries(self) -> Result { self.shared_decode_map() } #[inline] - fn decode_struct(self, _: Option) -> Result { + fn decode_struct(self, _: Option, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeStruct) -> Result, + { + let mut decoder = self.shared_decode_map()?; + let output = f(&mut decoder)?; + decoder.skip_map_remaining()?; + Ok(output) + } + + #[inline] + fn decode_struct_fields(self, _: Option) -> Result { self.shared_decode_map() } #[inline] - fn decode_variant(mut self) -> Result { + fn decode_variant(mut self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeVariant) -> Result, + { const VARIANT: Tag = Tag::from_mark(Mark::Variant); let tag = Tag::from_byte(self.reader.read_byte(self.cx)?); @@ -632,7 +743,7 @@ where })); } - Ok(self) + f(&mut self) } #[inline] @@ -703,12 +814,16 @@ where } }, Kind::Sequence => { - let sequence = self.shared_decode_sequence()?; - visitor.visit_sequence(cx, sequence) + let mut sequence = self.shared_decode_sequence()?; + let output = visitor.visit_sequence(cx, &mut sequence)?; + sequence.skip_sequence_remaining()?; + Ok(output) } Kind::Map => { - let map = self.shared_decode_map()?; - visitor.visit_map(cx, map) + let mut map = self.shared_decode_map()?; + let output = visitor.visit_map(cx, &mut map)?; + map.skip_map_remaining()?; + Ok(output) } Kind::Bytes => { let hint = tag @@ -731,10 +846,7 @@ where let value = self.decode_bool()?; visitor.visit_bool(cx, value) } - Mark::Variant => { - let value = self.decode_variant()?; - visitor.visit_variant(cx, value) - } + Mark::Variant => self.decode_variant(|decoder| visitor.visit_variant(cx, decoder)), Mark::Some | Mark::None => { let value = self.decode_option()?; visitor.visit_option(cx, value) @@ -754,62 +866,41 @@ where } } -impl<'a, 'de, R, const F: Options, C> PackDecoder<'de> for SelfDecoder<'a, Limit, F, C> +impl<'a, 'de, R, const OPT: Options, C> PackDecoder<'de> for SelfDecoder<'a, Limit, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeNext<'this> = StorageDecoder<'a, as Reader<'de>>::Mut<'this>, F, C> where Self: 'this; + type DecodeNext<'this> = StorageDecoder<'a, as Reader<'de>>::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_next(&mut self) -> Result, C::Error> { Ok(StorageDecoder::new(self.cx, self.reader.borrow_mut())) } - - #[inline] - fn end(mut self) -> Result<(), C::Error> { - if self.reader.remaining() > 0 { - self.reader.skip(self.cx, self.reader.remaining())?; - } - - Ok(()) - } } -impl<'a, 'de, R, const F: Options, C> PackDecoder<'de> for SelfTupleDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> TupleDecoder<'de> for SelfTupleDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeNext<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeNext<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_next(&mut self) -> Result, C::Error> { Ok(SelfDecoder::new(self.cx, self.reader.borrow_mut())) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) - } } -impl<'a, R, const F: Options, C: ?Sized> RemainingSelfDecoder<'a, R, F, C> { - #[inline] - fn new(remaining: usize, decoder: SelfDecoder<'a, R, F, C>) -> Self { - Self { remaining, decoder } - } -} - -impl<'a, 'de, R, const F: Options, C> SequenceDecoder<'de> for RemainingSelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> SequenceDecoder<'de> for RemainingSelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeNext<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeNext<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { @@ -823,40 +914,29 @@ where } self.remaining -= 1; - Ok(Some(SelfDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + + Ok(Some(SelfDecoder::new(self.cx, self.reader.borrow_mut()))) } } -#[musli::map_decoder] -impl<'a, 'de, R, const F: Options, C> MapDecoder<'de> for RemainingSelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> MapDecoder<'de> for RemainingSelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeEntry<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> + type DecodeEntry<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> + where + Self: 'this; + type DecodeRemainingEntries<'this> = RemainingSelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type IntoMapEntries = Self; - - #[inline] - fn cx(&self) -> &C { - self.decoder.cx - } #[inline] fn size_hint(&self) -> SizeHint { SizeHint::Exact(self.remaining) } - #[inline] - fn into_map_entries(self) -> Result { - Ok(self) - } - #[inline] fn decode_entry(&mut self) -> Result>, C::Error> { if self.remaining == 0 { @@ -864,23 +944,30 @@ where } self.remaining -= 1; - Ok(Some(SelfDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(SelfDecoder::new(self.cx, self.reader.borrow_mut()))) + } + + #[inline] + fn decode_remaining_entries(&mut self) -> Result, C::Error> { + Ok(RemainingSelfDecoder::new( + self.cx, + self.reader.borrow_mut(), + take(&mut self.remaining), + )) } } -impl<'a, 'de, R, const F: Options, C> MapEntriesDecoder<'de> for RemainingSelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> MapEntriesDecoder<'de> + for RemainingSelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeMapEntryKey<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> + type DecodeMapEntryKey<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type DecodeMapEntryValue<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> + type DecodeMapEntryValue<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; @@ -891,51 +978,49 @@ where } self.remaining -= 1; - Ok(Some(SelfDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(SelfDecoder::new(self.cx, self.reader.borrow_mut()))) } #[inline] fn decode_map_entry_value(&mut self) -> Result, C::Error> { - Ok(SelfDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + Ok(SelfDecoder::new(self.cx, self.reader.borrow_mut())) } #[inline] fn skip_map_entry_value(&mut self) -> Result { - self.decode_map_entry_value()?.skip_any()?; + self.decode_map_entry_value()?.skip()?; Ok(true) } + + #[inline] + fn end_map_entries(self) -> Result<(), ::Error> { + self.skip_map_remaining()?; + Ok(()) + } } -impl<'a, 'de, R, const F: Options, C> StructFieldsDecoder<'de> for RemainingSelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> StructFieldsDecoder<'de> + for RemainingSelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeStructFieldName<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> + type DecodeStructFieldName<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type DecodeStructFieldValue<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> + type DecodeStructFieldValue<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_struct_field_name(&mut self) -> Result, C::Error> { if self.remaining == 0 { - return Err(self.decoder.cx.message("Ran out of fields")); + return Err(self.cx.message("Ran out of fields")); } self.remaining -= 1; - Ok(SelfDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + Ok(SelfDecoder::new(self.cx, self.reader.borrow_mut())) } #[inline] @@ -949,18 +1034,18 @@ where } #[inline] - fn end(self) -> Result<(), C::Error> { - MapEntriesDecoder::end(self) + fn end_struct_fields(self) -> Result<(), C::Error> { + MapEntriesDecoder::end_map_entries(self) } } -impl<'a, 'de, R, const F: Options, C> MapEntryDecoder<'de> for SelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> MapEntryDecoder<'de> for SelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeMapKey<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeMapKey<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; type DecodeMapValue = Self; #[inline] @@ -980,51 +1065,34 @@ where } } -#[musli::struct_decoder] -impl<'a, 'de, R, const F: Options, C> StructDecoder<'de> for RemainingSelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> StructDecoder<'de> for RemainingSelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeField<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> + type DecodeField<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type IntoStructFields = Self; - - #[inline] - fn cx(&self) -> &C { - self.decoder.cx - } #[inline] fn size_hint(&self) -> SizeHint { SizeHint::Exact(self.remaining) } - #[inline] - fn into_struct_fields(self) -> Result { - Ok(self) - } - #[inline] fn decode_field(&mut self) -> Result>, C::Error> { MapDecoder::decode_entry(self) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - MapDecoder::end(self) - } } -impl<'a, 'de, R, const F: Options, C> StructFieldDecoder<'de> for SelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> StructFieldDecoder<'de> for SelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeFieldName<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeFieldName<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; type DecodeFieldValue = Self; #[inline] @@ -1043,14 +1111,14 @@ where } } -impl<'a, 'de, R, const F: Options, C> VariantDecoder<'de> for SelfDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> VariantDecoder<'de> for SelfDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { type Cx = C; - type DecodeTag<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; - type DecodeValue<'this> = SelfDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeTag<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; + type DecodeValue<'this> = SelfDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_tag(&mut self) -> Result, C::Error> { @@ -1064,14 +1132,9 @@ where #[inline] fn skip_value(&mut self) -> Result { - self.skip_any()?; + self.decode_value()?.skip()?; Ok(true) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) - } } struct Expected { diff --git a/crates/musli-descriptive/src/en.rs b/crates/musli-descriptive/src/en.rs index 85e41c278..2d829bde6 100644 --- a/crates/musli-descriptive/src/en.rs +++ b/crates/musli-descriptive/src/en.rs @@ -1,8 +1,8 @@ use core::fmt; use musli::en::{ - Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, SequenceEncoder, StructEncoder, - StructFieldEncoder, VariantEncoder, + Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, PackEncoder, SequenceEncoder, + StructEncoder, StructFieldEncoder, TupleEncoder, VariantEncoder, }; use musli::{Buf, Context, Encode}; use musli_common::int::continuation as c; @@ -19,12 +19,12 @@ use crate::writer::{BufWriter, Writer}; const VARIANT: Tag = Tag::from_mark(Mark::Variant); /// A very simple encoder. -pub struct SelfEncoder<'a, W, const F: Options, C: ?Sized> { +pub struct SelfEncoder<'a, W, const OPT: Options, C: ?Sized> { cx: &'a C, writer: W, } -impl<'a, W, const F: Options, C: ?Sized> SelfEncoder<'a, W, F, C> { +impl<'a, W, const OPT: Options, C: ?Sized> SelfEncoder<'a, W, OPT, C> { /// Construct a new fixed width message encoder. #[inline] pub(crate) fn new(cx: &'a C, writer: W) -> Self { @@ -32,13 +32,13 @@ impl<'a, W, const F: Options, C: ?Sized> SelfEncoder<'a, W, F, C> { } } -pub struct SelfPackEncoder<'a, W, B, const F: Options, C: ?Sized> { +pub struct SelfPackEncoder<'a, W, B, const OPT: Options, C: ?Sized> { cx: &'a C, writer: W, buffer: BufWriter, } -impl<'a, W, B, const F: Options, C: ?Sized> SelfPackEncoder<'a, W, B, F, C> { +impl<'a, W, B, const OPT: Options, C: ?Sized> SelfPackEncoder<'a, W, B, OPT, C> { /// Construct a new fixed width message encoder. #[inline] pub(crate) fn new(cx: &'a C, writer: W, buffer: B) -> Self { @@ -51,7 +51,7 @@ impl<'a, W, B, const F: Options, C: ?Sized> SelfPackEncoder<'a, W, B, F, C> { } #[musli::encoder] -impl<'a, W, const F: Options, C> Encoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> Encoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, @@ -60,8 +60,8 @@ where type Error = C::Error; type Ok = (); type Mode = C::Mode; - type WithContext<'this, U> = SelfEncoder<'this, W, F, U> where U: 'this + Context; - type EncodePack = SelfPackEncoder<'a, W, C::Buf<'a>, F, C>; + type WithContext<'this, U> = SelfEncoder<'this, W, OPT, U> where U: 'this + Context; + type EncodePack = SelfPackEncoder<'a, W, C::Buf<'a>, OPT, C>; type EncodeSome = Self; type EncodeSequence = Self; type EncodeTuple = Self; @@ -121,7 +121,7 @@ where #[inline] fn encode_bytes(mut self, bytes: &[u8]) -> Result { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), Kind::Bytes, bytes.len())?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Bytes, bytes.len())?; self.writer.write_bytes(self.cx, bytes)?; Ok(()) } @@ -132,7 +132,7 @@ where I: IntoIterator, I::Item: AsRef<[u8]>, { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), Kind::Bytes, len)?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Bytes, len)?; for bytes in vectors { self.writer.write_bytes(self.cx, bytes.as_ref())?; @@ -143,7 +143,7 @@ where #[inline] fn encode_string(mut self, string: &str) -> Result { - encode_prefix::<_, _, F>( + encode_prefix::<_, _, OPT>( self.cx, self.writer.borrow_mut(), Kind::String, @@ -264,31 +264,31 @@ where #[inline] fn encode_sequence(mut self, len: usize) -> Result { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), Kind::Sequence, len)?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Sequence, len)?; Ok(self) } #[inline] fn encode_tuple(mut self, len: usize) -> Result { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), Kind::Sequence, len)?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Sequence, len)?; Ok(self) } #[inline] fn encode_map(mut self, len: usize) -> Result { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), Kind::Map, len)?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Map, len)?; Ok(self) } #[inline] fn encode_map_entries(mut self, len: usize) -> Result { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), Kind::Map, len)?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Map, len)?; Ok(self) } #[inline] fn encode_struct(mut self, len: usize) -> Result { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), Kind::Map, len)?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), Kind::Map, len)?; Ok(self) } @@ -306,7 +306,7 @@ where let mut variant = self.encode_variant()?; variant.encode_tag()?.encode(tag)?; variant.encode_value()?.encode_unit()?; - VariantEncoder::end(variant)?; + VariantEncoder::end_variant(variant)?; Ok(()) } @@ -320,7 +320,7 @@ where T: ?Sized + Encode, { self.writer.write_byte(self.cx, VARIANT.byte())?; - SelfEncoder::<_, F, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; + SelfEncoder::<_, OPT, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; self.encode_tuple(len) } @@ -334,12 +334,12 @@ where T: ?Sized + Encode, { self.writer.write_byte(self.cx, VARIANT.byte())?; - SelfEncoder::<_, F, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; + SelfEncoder::<_, OPT, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; self.encode_struct(len) } } -impl<'a, W, B, const F: Options, C> SequenceEncoder for SelfPackEncoder<'a, W, B, F, C> +impl<'a, W, B, const OPT: Options, C> PackEncoder for SelfPackEncoder<'a, W, B, OPT, C> where W: Writer, B: Buf, @@ -347,15 +347,15 @@ where { type Cx = C; type Ok = (); - type EncodeNext<'this> = StorageEncoder<'a, &'this mut BufWriter, F, C> where Self: 'this; + type EncodePacked<'this> = StorageEncoder<'a, &'this mut BufWriter, OPT, C> where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_packed(&mut self) -> Result, C::Error> { Ok(StorageEncoder::new(self.cx, &mut self.buffer)) } #[inline] - fn end(mut self) -> Result { + fn end_pack(mut self) -> Result { static PAD: [u8; 1024] = [0; 1024]; let buffer = self.buffer.into_inner(); @@ -391,55 +391,75 @@ where } } -impl<'a, W, const F: Options, C> SequenceEncoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> SequenceEncoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, { type Cx = C; type Ok = (); - type EncodeNext<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeElement<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_element(&mut self) -> Result, C::Error> { Ok(SelfEncoder::new(self.cx, self.writer.borrow_mut())) } #[inline] - fn end(self) -> Result { + fn end_sequence(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEncoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> TupleEncoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, { type Cx = C; type Ok = (); - type EncodeEntry<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeTupleField<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_entry(&mut self) -> Result, C::Error> { + fn encode_tuple_field(&mut self) -> Result, C::Error> { + SequenceEncoder::encode_element(self) + } + + #[inline] + fn end_tuple(self) -> Result { + SequenceEncoder::end_sequence(self) + } +} + +impl<'a, W, const OPT: Options, C> MapEncoder for SelfEncoder<'a, W, OPT, C> +where + W: Writer, + C: ?Sized + Context, +{ + type Cx = C; + type Ok = (); + type EncodeMapEntry<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + + #[inline] + fn encode_map_entry(&mut self) -> Result, C::Error> { Ok(SelfEncoder::new(self.cx, self.writer.borrow_mut())) } #[inline] - fn end(self) -> Result { + fn end_map(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEntryEncoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> MapEntryEncoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, { type Cx = C; type Ok = (); - type EncodeMapKey<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeMapValue<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapKey<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeMapValue<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_map_key(&mut self) -> Result, C::Error> { @@ -452,20 +472,20 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entry(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEntriesEncoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> MapEntriesEncoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, { type Cx = C; type Ok = (); - type EncodeMapEntryKey<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeMapEntryValue<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapEntryKey<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeMapEntryValue<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_map_entry_key(&mut self) -> Result, C::Error> { @@ -478,40 +498,40 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entries(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> StructEncoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> StructEncoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, { type Cx = C; type Ok = (); - type EncodeField<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeStructField<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_field(&mut self) -> Result, C::Error> { - MapEncoder::encode_entry(self) + fn encode_struct_field(&mut self) -> Result, C::Error> { + MapEncoder::encode_map_entry(self) } #[inline] - fn end(self) -> Result { + fn end_struct(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> StructFieldEncoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> StructFieldEncoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, { type Cx = C; type Ok = (); - type EncodeFieldName<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeFieldValue<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeFieldName<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeFieldValue<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_field_name(&mut self) -> Result, C::Error> { @@ -524,20 +544,20 @@ where } #[inline] - fn end(self) -> Result { - MapEntryEncoder::end(self) + fn end_field(self) -> Result { + MapEntryEncoder::end_map_entry(self) } } -impl<'a, W, const F: Options, C> VariantEncoder for SelfEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> VariantEncoder for SelfEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, { type Cx = C; type Ok = (); - type EncodeTag<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeValue<'this> = SelfEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeTag<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeValue<'this> = SelfEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_tag(&mut self) -> Result, C::Error> { @@ -550,14 +570,14 @@ where } #[inline] - fn end(self) -> Result { + fn end_variant(self) -> Result { Ok(()) } } /// Encode a length prefix. #[inline] -fn encode_prefix( +fn encode_prefix( cx: &C, mut writer: W, kind: Kind, @@ -571,7 +591,7 @@ where writer.write_byte(cx, tag.byte())?; if !embedded { - musli_common::int::encode_usize::<_, _, F>(cx, writer, len)?; + musli_common::int::encode_usize::<_, _, OPT>(cx, writer, len)?; } Ok(()) diff --git a/crates/musli-descriptive/src/encoding.rs b/crates/musli-descriptive/src/encoding.rs index bcc752eb6..9ee6bbb72 100644 --- a/crates/musli-descriptive/src/encoding.rs +++ b/crates/musli-descriptive/src/encoding.rs @@ -99,7 +99,7 @@ where } /// Setting up encoding with parameters. -pub struct Encoding { +pub struct Encoding { _marker: marker::PhantomData, } @@ -140,7 +140,7 @@ impl Encoding { } } -impl Encoding { +impl Encoding { /// Change the mode of the encoding. pub const fn with_mode(self) -> Encoding { Encoding { @@ -148,15 +148,19 @@ impl Encoding { } } - musli_common::encoding_impls!(M, SelfEncoder::<_, F, _>::new, SelfDecoder::<_, F, _>::new); + musli_common::encoding_impls!( + M, + SelfEncoder::<_, OPT, _>::new, + SelfDecoder::<_, OPT, _>::new + ); musli_common::encoding_from_slice_impls!(M, SelfDecoder::<_, F>::new); } -impl Clone for Encoding { +impl Clone for Encoding { #[inline] fn clone(&self) -> Self { *self } } -impl Copy for Encoding {} +impl Copy for Encoding {} diff --git a/crates/musli-descriptive/src/test.rs b/crates/musli-descriptive/src/test.rs index ee6315b21..f73689e38 100644 --- a/crates/musli-descriptive/src/test.rs +++ b/crates/musli-descriptive/src/test.rs @@ -33,7 +33,7 @@ where where D: Decoder<'de, Mode = M>, { - decoder.decode_pack_fn(|pack| { + decoder.decode_pack(|pack| { let tag = pack.decode_next()?.decode()?; let value = pack.decode_next()?.decode()?; Ok(Self { tag, value }) diff --git a/crates/musli-json/src/de/key_decoder.rs b/crates/musli-json/src/de/key_decoder.rs index 49afcca45..5095ed21b 100644 --- a/crates/musli-json/src/de/key_decoder.rs +++ b/crates/musli-json/src/de/key_decoder.rs @@ -5,9 +5,7 @@ use musli::Context; use crate::parser::{Parser, Token}; -use super::{ - JsonDecoder, JsonObjectDecoder, KeySignedVisitor, KeyUnsignedVisitor, StringReference, -}; +use super::{JsonDecoder, KeySignedVisitor, KeyUnsignedVisitor, StringReference}; /// A JSON object key decoder for Müsli. pub(crate) struct JsonKeyDecoder<'a, P, C: ?Sized> { @@ -26,11 +24,6 @@ where Self { cx, parser } } - #[inline] - pub(super) fn skip_any(self) -> Result<(), C::Error> { - JsonDecoder::new(self.cx, self.parser).skip_any() - } - #[inline] fn decode_escaped_bytes(mut self, visitor: V) -> Result where @@ -57,7 +50,6 @@ where type Error = C::Error; type Mode = C::Mode; type WithContext<'this, U> = JsonKeyDecoder<'this, P, U> where U: 'this + Context; - type DecodeStruct = JsonObjectDecoder<'a, P, C>; #[inline] fn cx(&self) -> &Self::Cx { @@ -87,7 +79,7 @@ where #[inline] fn skip(self) -> Result<(), C::Error> { - self.skip_any() + JsonDecoder::new(self.cx, self.parser).skip() } #[inline] diff --git a/crates/musli-json/src/de/mod.rs b/crates/musli-json/src/de/mod.rs index e4fa709dc..43dcbb683 100644 --- a/crates/musli-json/src/de/mod.rs +++ b/crates/musli-json/src/de/mod.rs @@ -26,8 +26,8 @@ use core::str; use alloc::vec::Vec; use musli::de::{ - Decode, Decoder, MapDecoder, MapEntryDecoder, NumberHint, NumberVisitor, SequenceDecoder, - SizeHint, TypeHint, ValueVisitor, Visitor, + Decode, Decoder, NumberHint, NumberVisitor, SequenceDecoder, SizeHint, TypeHint, ValueVisitor, + Visitor, }; use musli::Context; @@ -67,25 +67,8 @@ where let actual = self.parser.peek(self.cx)?; match actual { - Token::OpenBrace => { - let mut object = JsonObjectDecoder::new(self.cx, None, self.parser)?; - - while let Some(mut pair) = object.decode_entry()? { - pair.decode_map_key()?.skip()?; - pair.skip_map_value()?; - } - - Ok(()) - } - Token::OpenBracket => { - let mut seq = JsonSequenceDecoder::new(self.cx, None, self.parser)?; - - while let Some(item) = SequenceDecoder::decode_next(&mut seq)? { - item.skip_any()?; - } - - Ok(()) - } + Token::OpenBrace => self.decode_map(|_| Ok(())), + Token::OpenBracket => self.decode_sequence(|_| Ok(())), Token::Null => self.parse_null(), Token::True => self.parse_true(), Token::False => self.parse_false(), @@ -133,8 +116,10 @@ where type DecodeSequence = JsonSequenceDecoder<'a, P, C>; type DecodeTuple = JsonSequenceDecoder<'a, P, C>; type DecodeMap = JsonObjectDecoder<'a, P, C>; + type DecodeMapEntries = JsonObjectDecoder<'a, P, C>; type DecodeSome = JsonDecoder<'a, P, C>; type DecodeStruct = JsonObjectDecoder<'a, P, C>; + type DecodeStructFields = JsonObjectDecoder<'a, P, C>; type DecodeVariant = JsonVariantDecoder<'a, P, C>; #[inline] @@ -163,6 +148,12 @@ where T::decode(self.cx, self) } + #[inline] + fn skip(self) -> Result<(), C::Error> { + self.skip_any()?; + Ok(()) + } + #[inline] fn type_hint(&mut self) -> Result { Ok(match self.parser.peek(self.cx)? { @@ -187,7 +178,7 @@ where #[inline] fn decode_unit(self) -> Result<(), C::Error> { - self.skip_any() + self.skip() } #[inline] @@ -305,28 +296,30 @@ where fn decode_array(self) -> Result<[u8; N], C::Error> { let cx = self.cx; let mark = cx.mark(); - let mut seq = self.decode_sequence()?; - let mut bytes = [0; N]; - let mut index = 0; - while let Some(item) = SequenceDecoder::decode_next(&mut seq)? { - if index <= N { - bytes[index] = item.decode_u8()?; - } + self.decode_sequence(|seq| { + let mut bytes = [0; N]; + let mut index = 0; - index += 1; - } + while let Some(item) = seq.decode_next()? { + if index <= N { + bytes[index] = item.decode_u8()?; + } - if index != N { - return Err(cx.marked_message( - mark, - format_args!( - "Array with length {index} does not have the expected {N} number of elements" - ), - )); - } + index += 1; + } - Ok(bytes) + if index != N { + return Err(cx.marked_message( + mark, + format_args!( + "Array with length {index} does not have the expected {N} number of elements" + ), + )); + } + + Ok(bytes) + }) } #[inline] @@ -344,14 +337,16 @@ where V: ValueVisitor<'de, C, [u8]>, { let cx = self.cx; - let mut seq = self.decode_sequence()?; - let mut bytes = Vec::with_capacity(seq.size_hint().or_default()); - while let Some(item) = SequenceDecoder::decode_next(&mut seq)? { - bytes.push(item.decode_u8()?); - } + self.decode_sequence(|seq| { + let mut bytes = Vec::with_capacity(seq.size_hint().or_default()); - visitor.visit_owned(cx, bytes) + while let Some(item) = seq.decode_next()? { + bytes.push(item.decode_u8()?); + } + + visitor.visit_owned(cx, bytes) + }) } #[inline] @@ -380,33 +375,82 @@ where } #[inline] - fn decode_pack(self) -> Result { - JsonSequenceDecoder::new(self.cx, None, self.parser) + fn decode_pack(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodePack) -> Result, + { + let mut decoder = JsonSequenceDecoder::new(self.cx, None, self.parser)?; + let output = f(&mut decoder)?; + decoder.skip_sequence_remaining()?; + Ok(output) } #[inline] - fn decode_sequence(self) -> Result { - JsonSequenceDecoder::new(self.cx, None, self.parser) + fn decode_sequence(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeSequence) -> Result, + { + let mut decoder = JsonSequenceDecoder::new(self.cx, None, self.parser)?; + let output = f(&mut decoder)?; + decoder.skip_sequence_remaining()?; + Ok(output) } #[inline] - fn decode_tuple(self, len: usize) -> Result { - JsonSequenceDecoder::new(self.cx, Some(len), self.parser) + fn decode_tuple(self, len: usize, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeTuple) -> Result, + { + let mut decoder = JsonSequenceDecoder::new(self.cx, Some(len), self.parser)?; + let output = f(&mut decoder)?; + decoder.skip_sequence_remaining()?; + Ok(output) } #[inline] - fn decode_map(self) -> Result { + fn decode_map(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeMap) -> Result, + { + let mut decoder = JsonObjectDecoder::new(self.cx, None, self.parser)?; + let output = f(&mut decoder)?; + decoder.skip_object_remaining()?; + Ok(output) + } + + #[inline] + fn decode_map_entries(self) -> Result { JsonObjectDecoder::new(self.cx, None, self.parser) } #[inline] - fn decode_struct(self, len: Option) -> Result { + fn decode_struct(self, len: Option, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeStruct) -> Result, + { + let mut decoder = JsonObjectDecoder::new(self.cx, len, self.parser)?; + let output = f(&mut decoder)?; + decoder.skip_object_remaining()?; + Ok(output) + } + + #[inline] + fn decode_struct_fields( + self, + len: Option, + ) -> Result { JsonObjectDecoder::new(self.cx, len, self.parser) } #[inline] - fn decode_variant(self) -> Result { - JsonVariantDecoder::new(self.cx, self.parser) + fn decode_variant(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeVariant) -> Result, + { + let mut decoder = JsonVariantDecoder::new(self.cx, self.parser)?; + let output = f(&mut decoder)?; + decoder.end()?; + Ok(output) } #[inline] @@ -415,16 +459,11 @@ where V: Visitor<'de, C>, { let cx = self.cx; - self.parser.skip_whitespace(cx)?; match self.parser.peek(cx)? { - Token::OpenBrace => { - let decoder = JsonObjectDecoder::new(self.cx, None, self.parser)?; - visitor.visit_map(cx, decoder) - } + Token::OpenBrace => self.decode_map(|decoder| visitor.visit_map(cx, decoder)), Token::OpenBracket => { - let decoder = JsonSequenceDecoder::new(self.cx, None, self.parser)?; - visitor.visit_sequence(cx, decoder) + self.decode_sequence(|decoder| visitor.visit_sequence(cx, decoder)) } Token::String => { let visitor = visitor.visit_string(cx, SizeHint::Any)?; diff --git a/crates/musli-json/src/de/object_decoder.rs b/crates/musli-json/src/de/object_decoder.rs index cb8d0ff82..227f3ecba 100644 --- a/crates/musli-json/src/de/object_decoder.rs +++ b/crates/musli-json/src/de/object_decoder.rs @@ -1,18 +1,22 @@ -use core::mem; +use core::mem::{replace, take}; -use musli::de::{MapDecoder, MapEntriesDecoder, SizeHint, StructDecoder, StructFieldsDecoder}; +use musli::de::{ + Decoder, MapDecoder, MapEntriesDecoder, MapEntryDecoder, SizeHint, StructDecoder, + StructFieldsDecoder, +}; use musli::Context; use crate::parser::{Parser, Token}; use super::{JsonDecoder, JsonKeyDecoder, JsonObjectPairDecoder}; +#[must_use = "Must call skip_object_remaining to complete decoding"] pub(crate) struct JsonObjectDecoder<'a, P, C: ?Sized> { cx: &'a C, first: bool, - completed: bool, len: Option, parser: P, + finalized: bool, } impl<'a, 'de, P, C> JsonObjectDecoder<'a, P, C> @@ -20,10 +24,23 @@ where P: Parser<'de>, C: ?Sized + Context, { + pub(super) fn new_in( + cx: &'a C, + first: bool, + len: Option, + parser: P, + ) -> Result { + Ok(Self { + cx, + first, + len, + parser, + finalized: false, + }) + } + #[inline] pub(super) fn new(cx: &'a C, len: Option, mut parser: P) -> Result { - parser.skip_whitespace(cx)?; - let actual = parser.peek(cx)?; if !matches!(actual, Token::OpenBrace) { @@ -35,28 +52,30 @@ where Ok(Self { cx, first: true, - completed: false, len, parser, + finalized: false, }) } fn parse_map_key(&mut self) -> Result { - let first = mem::take(&mut self.first); + if self.finalized { + return Ok(false); + } + + let first = take(&mut self.first); loop { let token = self.parser.peek(self.cx)?; - if token.is_string() { - return Ok(true); - } - match token { + Token::String => { + return Ok(true); + } Token::Comma if !first => { self.parser.skip(self.cx, 1)?; } Token::CloseBrace => { - self.parser.skip(self.cx, 1)?; return Ok(false); } token => { @@ -67,9 +86,34 @@ where } } } + + /// Parse end of object. + #[inline] + pub(super) fn skip_object_remaining(mut self) -> Result<(), C::Error> { + // Someone else is responsible for finalizing this decoder. + if self.finalized { + return Ok(()); + } + + while let Some(mut entry) = self.decode_entry()? { + entry.decode_map_key()?.skip()?; + entry.skip_map_value()?; + } + + let actual = self.parser.peek(self.cx)?; + + if !matches!(actual, Token::CloseBrace) { + return Err(self + .cx + .message(format_args!("Expected closing brace `}}`, was {actual}"))); + } + + self.parser.skip(self.cx, 1)?; + self.finalized = true; + Ok(()) + } } -#[musli::map_decoder] impl<'a, 'de, P, C> MapDecoder<'de> for JsonObjectDecoder<'a, P, C> where P: Parser<'de>, @@ -79,23 +123,15 @@ where type DecodeEntry<'this> = JsonObjectPairDecoder<'a, P::Mut<'this>, C> where Self: 'this; - type IntoMapEntries = Self; - - #[inline] - fn cx(&self) -> &Self::Cx { - self.cx - } + type DecodeRemainingEntries<'this> = JsonObjectDecoder<'a, P::Mut<'this>, C> + where + Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { SizeHint::from(self.len) } - #[inline] - fn into_map_entries(self) -> Result { - Ok(self) - } - #[inline] fn decode_entry(&mut self) -> Result>, C::Error> { if !self.parse_map_key()? { @@ -109,8 +145,16 @@ where } #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) + fn decode_remaining_entries( + &mut self, + ) -> Result, ::Error> { + if replace(&mut self.finalized, true) { + return Err(self + .cx + .message("Cannot decode remaining entries after finalizing")); + } + + JsonObjectDecoder::new_in(self.cx, self.first, self.len, self.parser.borrow_mut()) } } @@ -127,12 +171,7 @@ where #[inline] fn decode_map_entry_key(&mut self) -> Result>, C::Error> { - if self.completed { - return Ok(None); - } - if !self.parse_map_key()? { - self.completed = true; return Ok(None); } @@ -155,21 +194,16 @@ where #[inline] fn skip_map_entry_value(&mut self) -> Result { - let actual = self.parser.peek(self.cx)?; - - if !matches!(actual, Token::Colon) { - return Err(self - .cx - .message(format_args!("Expected colon `:`, was {actual}"))); - } - - self.parser.skip(self.cx, 1)?; - JsonDecoder::new(self.cx, self.parser.borrow_mut()).skip_any()?; + self.decode_map_entry_value()?.skip()?; Ok(true) } + + #[inline] + fn end_map_entries(self) -> Result<(), C::Error> { + self.skip_object_remaining() + } } -#[musli::struct_decoder] impl<'a, 'de, P, C> StructDecoder<'de> for JsonObjectDecoder<'a, P, C> where P: Parser<'de>, @@ -179,32 +213,16 @@ where type DecodeField<'this> = JsonObjectPairDecoder<'a, P::Mut<'this>, C> where Self: 'this; - type IntoStructFields = Self; - - #[inline] - fn cx(&self) -> &Self::Cx { - self.cx - } #[inline] fn size_hint(&self) -> SizeHint { MapDecoder::size_hint(self) } - #[inline] - fn into_struct_fields(self) -> Result { - Ok(self) - } - #[inline] fn decode_field(&mut self) -> Result>, C::Error> { MapDecoder::decode_entry(self) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - MapDecoder::end(self) - } } impl<'a, 'de, P, C> StructFieldsDecoder<'de> for JsonObjectDecoder<'a, P, C> @@ -220,36 +238,27 @@ where #[inline] fn decode_struct_field_name(&mut self) -> Result, C::Error> { - if !self.parse_map_key()? { - return Err(self - .cx - .message("Expected map key, but found closing brace `}`")); - } + let cx = self.cx; + + let Some(decoder) = self.decode_map_entry_key()? else { + return Err(cx.message("Expected struct field")); + }; - Ok(JsonKeyDecoder::new(self.cx, self.parser.borrow_mut())) + Ok(decoder) } #[inline] fn decode_struct_field_value(&mut self) -> Result, C::Error> { - let actual = self.parser.peek(self.cx)?; - - if !matches!(actual, Token::Colon) { - return Err(self - .cx - .message(format_args!("Expected colon `:`, was {actual}"))); - } - - self.parser.skip(self.cx, 1)?; - Ok(JsonDecoder::new(self.cx, self.parser.borrow_mut())) + self.decode_map_entry_value() } #[inline] fn skip_struct_field_value(&mut self) -> Result { - MapEntriesDecoder::skip_map_entry_value(self) + self.skip_map_entry_value() } #[inline] - fn end(self) -> Result<(), C::Error> { - MapEntriesDecoder::end(self) + fn end_struct_fields(self) -> Result<(), C::Error> { + self.end_map_entries() } } diff --git a/crates/musli-json/src/de/object_pair_decoder.rs b/crates/musli-json/src/de/object_pair_decoder.rs index 150141842..203944a1a 100644 --- a/crates/musli-json/src/de/object_pair_decoder.rs +++ b/crates/musli-json/src/de/object_pair_decoder.rs @@ -1,4 +1,4 @@ -use musli::de::{MapEntryDecoder, StructFieldDecoder}; +use musli::de::{Decoder, MapEntryDecoder, StructFieldDecoder}; use musli::Context; use crate::parser::{Parser, Token}; @@ -48,17 +48,8 @@ where } #[inline] - fn skip_map_value(mut self) -> Result { - let actual = self.parser.peek(self.cx)?; - - if !matches!(actual, Token::Colon) { - return Err(self - .cx - .message(format_args!("Expected colon `:`, was {actual}"))); - } - - self.parser.skip(self.cx, 1)?; - JsonDecoder::new(self.cx, self.parser.borrow_mut()).skip_any()?; + fn skip_map_value(self) -> Result { + self.decode_map_value()?.skip()?; Ok(true) } } diff --git a/crates/musli-json/src/de/sequence_decoder.rs b/crates/musli-json/src/de/sequence_decoder.rs index 4eeee0432..752925070 100644 --- a/crates/musli-json/src/de/sequence_decoder.rs +++ b/crates/musli-json/src/de/sequence_decoder.rs @@ -1,18 +1,19 @@ use core::mem; -use musli::de::{PackDecoder, SequenceDecoder, SizeHint}; +use musli::de::{Decoder, PackDecoder, SequenceDecoder, SizeHint, TupleDecoder}; use musli::Context; use crate::parser::{Parser, Token}; use super::JsonDecoder; +#[must_use = "Must call skip_sequence_remaining"] pub(crate) struct JsonSequenceDecoder<'a, P, C: ?Sized> { cx: &'a C, len: Option, first: bool, parser: P, - terminated: bool, + finalized: bool, } impl<'a, 'de, P, C> JsonSequenceDecoder<'a, P, C> @@ -21,7 +22,7 @@ where C: ?Sized + Context, { #[inline] - pub(crate) fn new(cx: &'a C, len: Option, mut parser: P) -> Result { + pub(super) fn new(cx: &'a C, len: Option, mut parser: P) -> Result { let actual = parser.peek(cx)?; if !matches!(actual, Token::OpenBracket) { @@ -35,39 +36,18 @@ where len, first: true, parser, - terminated: false, + finalized: false, }) } -} - -impl<'a, 'de, P, C> SequenceDecoder<'de> for JsonSequenceDecoder<'a, P, C> -where - P: Parser<'de>, - C: ?Sized + Context, -{ - type Cx = C; - type DecodeNext<'this> = JsonDecoder<'a, P::Mut<'this>, C> - where - Self: 'this; - - #[inline] - fn size_hint(&self) -> SizeHint { - SizeHint::from(self.len) - } - - #[inline] - fn decode_next(&mut self) -> Result>, C::Error> { - if self.terminated { - return Ok(None); - } + fn parse_next_value(&mut self) -> Result { let first = mem::take(&mut self.first); loop { let token = self.parser.peek(self.cx)?; if token.is_value() { - return Ok(Some(JsonDecoder::new(self.cx, self.parser.borrow_mut()))); + return Ok(true); } match token { @@ -75,9 +55,7 @@ where self.parser.skip(self.cx, 1)?; } Token::CloseBracket => { - self.parser.skip(self.cx, 1)?; - self.terminated = true; - return Ok(None); + return Ok(false); } _ => { return Err(self.cx.message(format_args!( @@ -87,9 +65,32 @@ where } } } + + #[inline] + pub(super) fn skip_sequence_remaining(mut self) -> Result<(), C::Error> { + if self.finalized { + return Ok(()); + } + + while let Some(decoder) = SequenceDecoder::decode_next(&mut self)? { + decoder.skip()?; + } + + let actual = self.parser.peek(self.cx)?; + + if !matches!(actual, Token::CloseBracket) { + return Err(self + .cx + .message(format_args!("Expected closing bracket, was {actual}"))); + } + + self.parser.skip(self.cx, 1)?; + self.finalized = true; + Ok(()) + } } -impl<'a, 'de, P, C> PackDecoder<'de> for JsonSequenceDecoder<'a, P, C> +impl<'a, 'de, P, C> SequenceDecoder<'de> for JsonSequenceDecoder<'a, P, C> where P: Parser<'de>, C: ?Sized + Context, @@ -100,52 +101,52 @@ where Self: 'this; #[inline] - fn decode_next(&mut self) -> Result, C::Error> { - let first = mem::take(&mut self.first); + fn size_hint(&self) -> SizeHint { + SizeHint::from(self.len) + } - loop { - let token = self.parser.peek(self.cx)?; + #[inline] + fn decode_next(&mut self) -> Result>, C::Error> { + if !self.parse_next_value()? { + return Ok(None); + } - if token.is_value() { - return Ok(JsonDecoder::new(self.cx, self.parser.borrow_mut())); - } + Ok(Some(JsonDecoder::new(self.cx, self.parser.borrow_mut()))) + } +} - match token { - Token::Comma if !first => { - self.parser.skip(self.cx, 1)?; - } - Token::CloseBracket => { - self.parser.skip(self.cx, 1)?; - self.terminated = true; +impl<'a, 'de, P, C> PackDecoder<'de> for JsonSequenceDecoder<'a, P, C> +where + P: Parser<'de>, + C: ?Sized + Context, +{ + type Cx = C; + type DecodeNext<'this> = JsonDecoder<'a, P::Mut<'this>, C> + where + Self: 'this; - return Err(self - .cx - .message(format_args!("Encountered short array, but found {token}"))); - } - _ => { - return Err(self.cx.message(format_args!( - "Expected value or closing bracket `]`, but found {token}" - ))); - } - } + #[inline] + fn decode_next(&mut self) -> Result, C::Error> { + if !self.parse_next_value()? { + return Err(self.cx.message(format_args!("Encountered short array"))); } - } - #[inline] - fn end(mut self) -> Result<(), C::Error> { - if !self.terminated { - let actual = self.parser.peek(self.cx)?; - - if !matches!(actual, Token::CloseBracket) { - return Err(self - .cx - .message(format_args!("Expected closing bracket, was {actual}"))); - } + Ok(JsonDecoder::new(self.cx, self.parser.borrow_mut())) + } +} - self.parser.skip(self.cx, 1)?; - self.terminated = true; - } +impl<'a, 'de, P, C> TupleDecoder<'de> for JsonSequenceDecoder<'a, P, C> +where + P: Parser<'de>, + C: ?Sized + Context, +{ + type Cx = C; + type DecodeNext<'this> = JsonDecoder<'a, P::Mut<'this>, C> + where + Self: 'this; - Ok(()) + #[inline] + fn decode_next(&mut self) -> Result, C::Error> { + PackDecoder::decode_next(self) } } diff --git a/crates/musli-json/src/de/variant_decoder.rs b/crates/musli-json/src/de/variant_decoder.rs index b023556b6..0b2ebeb53 100644 --- a/crates/musli-json/src/de/variant_decoder.rs +++ b/crates/musli-json/src/de/variant_decoder.rs @@ -16,9 +16,7 @@ where C: ?Sized + Context, { #[inline] - pub(crate) fn new(cx: &'a C, mut parser: P) -> Result { - parser.skip_whitespace(cx)?; - + pub(super) fn new(cx: &'a C, mut parser: P) -> Result { let actual = parser.peek(cx)?; if !matches!(actual, Token::OpenBrace) { @@ -26,9 +24,22 @@ where } parser.skip(cx, 1)?; - Ok(Self { cx, parser }) } + + #[inline] + pub(super) fn end(mut self) -> Result<(), C::Error> { + let actual = self.parser.peek(self.cx)?; + + if !matches!(actual, Token::CloseBrace) { + return Err(self.cx.message(format_args!( + "Expected closing brace for variant, was {actual}" + ))); + } + + self.parser.skip(self.cx, 1)?; + Ok(()) + } } impl<'a, 'de, P, C> VariantDecoder<'de> for JsonVariantDecoder<'a, P, C> @@ -66,18 +77,4 @@ where self.decode_value()?.skip()?; Ok(true) } - - #[inline] - fn end(mut self) -> Result<(), C::Error> { - let actual = self.parser.peek(self.cx)?; - - if !matches!(actual, Token::CloseBrace) { - return Err(self - .cx - .message(format_args!("Expected closing brace, was {actual}"))); - } - - self.parser.skip(self.cx, 1)?; - Ok(()) - } } diff --git a/crates/musli-json/src/en/array_encoder.rs b/crates/musli-json/src/en/array_encoder.rs index fe1329ffd..91016f583 100644 --- a/crates/musli-json/src/en/array_encoder.rs +++ b/crates/musli-json/src/en/array_encoder.rs @@ -1,6 +1,6 @@ use core::mem::take; -use musli::en::SequenceEncoder; +use musli::en::{PackEncoder, SequenceEncoder, TupleEncoder}; use musli::Context; use crate::writer::Writer; @@ -45,12 +45,12 @@ where { type Cx = C; type Ok = (); - type EncodeNext<'this> = JsonEncoder<'a, W::Mut<'this>, C> + type EncodeElement<'this> = JsonEncoder<'a, W::Mut<'this>, C> where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_element(&mut self) -> Result, C::Error> { if !take(&mut self.first) { self.writer.write_byte(self.cx, b',')?; } @@ -59,7 +59,51 @@ where } #[inline] - fn end(mut self) -> Result { + fn end_sequence(mut self) -> Result { self.writer.write_bytes(self.cx, self.end) } } + +impl<'a, W, C> PackEncoder for JsonArrayEncoder<'a, W, C> +where + W: Writer, + C: ?Sized + Context, +{ + type Cx = C; + type Ok = (); + type EncodePacked<'this> = JsonEncoder<'a, W::Mut<'this>, C> + where + Self: 'this; + + #[inline] + fn encode_packed(&mut self) -> Result, C::Error> { + SequenceEncoder::encode_element(self) + } + + #[inline] + fn end_pack(self) -> Result { + SequenceEncoder::end_sequence(self) + } +} + +impl<'a, W, C> TupleEncoder for JsonArrayEncoder<'a, W, C> +where + W: Writer, + C: ?Sized + Context, +{ + type Cx = C; + type Ok = (); + type EncodeTupleField<'this> = JsonEncoder<'a, W::Mut<'this>, C> + where + Self: 'this; + + #[inline] + fn encode_tuple_field(&mut self) -> Result, C::Error> { + SequenceEncoder::encode_element(self) + } + + #[inline] + fn end_tuple(self) -> Result { + SequenceEncoder::end_sequence(self) + } +} diff --git a/crates/musli-json/src/en/mod.rs b/crates/musli-json/src/en/mod.rs index 21d53de71..20eba04e0 100644 --- a/crates/musli-json/src/en/mod.rs +++ b/crates/musli-json/src/en/mod.rs @@ -242,7 +242,7 @@ where } } - seq.end() + seq.end_sequence() } #[inline] diff --git a/crates/musli-json/src/en/object_encoder.rs b/crates/musli-json/src/en/object_encoder.rs index 1c1013720..79cd2b63a 100644 --- a/crates/musli-json/src/en/object_encoder.rs +++ b/crates/musli-json/src/en/object_encoder.rs @@ -42,12 +42,12 @@ where { type Cx = C; type Ok = (); - type EncodeEntry<'this> = JsonObjectPairEncoder<'a, W::Mut<'this>, C> + type EncodeMapEntry<'this> = JsonObjectPairEncoder<'a, W::Mut<'this>, C> where Self: 'this; #[inline] - fn encode_entry(&mut self) -> Result, C::Error> { + fn encode_map_entry(&mut self) -> Result, C::Error> { self.len += 1; Ok(JsonObjectPairEncoder::new( @@ -58,7 +58,7 @@ where } #[inline] - fn end(mut self) -> Result { + fn end_map(mut self) -> Result { self.writer.write_bytes(self.cx, self.end) } } @@ -92,7 +92,7 @@ where } #[inline] - fn end(mut self) -> Result { + fn end_map_entries(mut self) -> Result { self.writer.write_byte(self.cx, b'}') } } @@ -104,17 +104,17 @@ where { type Cx = C; type Ok = (); - type EncodeField<'this> = JsonObjectPairEncoder<'a, W::Mut<'this>, C> + type EncodeStructField<'this> = JsonObjectPairEncoder<'a, W::Mut<'this>, C> where Self: 'this; #[inline] - fn encode_field(&mut self) -> Result, C::Error> { - MapEncoder::encode_entry(self) + fn encode_struct_field(&mut self) -> Result, C::Error> { + MapEncoder::encode_map_entry(self) } #[inline] - fn end(self) -> Result { - MapEncoder::end(self) + fn end_struct(self) -> Result { + MapEncoder::end_map(self) } } diff --git a/crates/musli-json/src/en/object_pair_encoder.rs b/crates/musli-json/src/en/object_pair_encoder.rs index 4914ddf48..4518eb442 100644 --- a/crates/musli-json/src/en/object_pair_encoder.rs +++ b/crates/musli-json/src/en/object_pair_encoder.rs @@ -47,7 +47,7 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entry(self) -> Result { Ok(()) } } @@ -75,7 +75,7 @@ where } #[inline] - fn end(self) -> Result { - MapEntryEncoder::end(self) + fn end_field(self) -> Result { + MapEntryEncoder::end_map_entry(self) } } diff --git a/crates/musli-json/src/en/variant_encoder.rs b/crates/musli-json/src/en/variant_encoder.rs index a19dad7bf..22065aad2 100644 --- a/crates/musli-json/src/en/variant_encoder.rs +++ b/crates/musli-json/src/en/variant_encoder.rs @@ -49,7 +49,7 @@ where } #[inline] - fn end(mut self) -> Result { + fn end_variant(mut self) -> Result { self.writer.write_byte(self.cx, b'}') } } diff --git a/crates/musli-json/src/parser/token.rs b/crates/musli-json/src/parser/token.rs index df74fa647..04c96b992 100644 --- a/crates/musli-json/src/parser/token.rs +++ b/crates/musli-json/src/parser/token.rs @@ -61,12 +61,6 @@ impl Token { } } - /// Test if token is a string. - #[inline] - pub(crate) fn is_string(&self) -> bool { - matches!(self, Token::String) - } - #[inline] pub(crate) fn is_value(&self) -> bool { (*self as u8) & VAL_BIT != 0 diff --git a/crates/musli-macros/src/de.rs b/crates/musli-macros/src/de.rs index 38234b39e..d5711557d 100644 --- a/crates/musli-macros/src/de.rs +++ b/crates/musli-macros/src/de.rs @@ -317,7 +317,7 @@ fn decode_enum(cx: &Ctxt<'_>, e: &Build<'_>, en: &Enum) -> Result { #output_enum #enter - let #output_var = #decoder_t::decode_variant_fn(#decoder_var, |#variant_decoder_var| { + let #output_var = #decoder_t::decode_variant(#decoder_var, |#variant_decoder_var| { #variant_alloc let #variant_tag_var #name_type = { @@ -469,7 +469,7 @@ fn decode_enum(cx: &Ctxt<'_>, e: &Build<'_>, en: &Enum) -> Result { let #buffer_var = #decoder_t::decode_buffer(#decoder_var)?; let st = #as_decoder_t::as_decoder(&#buffer_var)?; - let #variant_tag_var = #decoder_t::decode_struct_fn(st, None, |st| { + let #variant_tag_var = #decoder_t::decode_struct(st, None, |st| { let #variant_tag_var #name_type = { let #variant_decoder_var = loop { let #option_some(mut #entry_var) = #struct_decoder_t::decode_field(st)? else { @@ -650,7 +650,7 @@ fn decode_enum(cx: &Ctxt<'_>, e: &Build<'_>, en: &Enum) -> Result { #enter - #decoder_t::decode_struct_fn(#decoder_var, None, |#struct_decoder_var| { + #decoder_t::decode_struct(#decoder_var, None, |#struct_decoder_var| { let mut #tag_var = #option_none; let #output_var = loop { @@ -969,7 +969,7 @@ fn decode_tagged( #(#decls)* #enter - #decoder_t::decode_struct_fn(#decoder_var, Some(#fields_len), |type_decoder| { + #decoder_t::decode_struct(#decoder_var, Some(#fields_len), |type_decoder| { while let #option_some(mut #struct_decoder_var) = #struct_decoder_t::decode_field(type_decoder)? { #field_alloc #tag_stmt @@ -1089,7 +1089,7 @@ fn decode_packed(cx: &Ctxt<'_>, e: &Build<'_>, st_: &Body<'_>) -> Result { encode = quote! { #enter - let #sequence_decoder_next_var = #sequence_encoder_t::encode_next(#pack_var)?; + let #sequence_decoder_next_var = #pack_encoder_t::encode_packed(#pack_var)?; #encode_path(#access, #ctx_var, #sequence_decoder_next_var)?; #leave }; @@ -413,7 +413,7 @@ fn encode_variant( encode = quote! {{ #encoder_t::encode_struct_fn(#encoder_var, 0, |#encoder_var| { - #struct_encoder_t::insert_field(#encoder_var, #field_tag, #tag)?; + #struct_encoder_t::insert_struct_field(#encoder_var, #field_tag, #tag)?; #(#decls)* #(#encoders)* #result_ok(()) @@ -440,9 +440,9 @@ fn encode_variant( encode = quote! {{ #encoder_t::encode_struct_fn(#encoder_var, 2, |#struct_encoder| { - #struct_encoder_t::insert_field(#struct_encoder, &#field_tag, #tag)?; + #struct_encoder_t::insert_struct_field(#struct_encoder, &#field_tag, #tag)?; - #struct_encoder_t::encode_field_fn(#struct_encoder, |#pair| { + #struct_encoder_t::encode_struct_field_fn(#struct_encoder, |#pair| { let #content_tag = #struct_field_encoder_t::encode_field_name(#pair)?; #encode_t_encode(&#content, #ctx_var, #content_tag)?; diff --git a/crates/musli-macros/src/internals/tokens.rs b/crates/musli-macros/src/internals/tokens.rs index 1a6f39d71..6cbf3a626 100644 --- a/crates/musli-macros/src/internals/tokens.rs +++ b/crates/musli-macros/src/internals/tokens.rs @@ -6,25 +6,25 @@ pub(crate) struct Tokens { pub(crate) buf_t: syn::Path, pub(crate) context_t: syn::Path, pub(crate) core_result: syn::Path, - pub(crate) decode_t: syn::Path, pub(crate) decode_bytes_t: syn::Path, + pub(crate) decode_t: syn::Path, pub(crate) decoder_t: syn::Path, pub(crate) default_function: syn::Path, pub(crate) default_mode: syn::Path, - pub(crate) encode_t: syn::Path, pub(crate) encode_bytes_t: syn::Path, + pub(crate) encode_t: syn::Path, pub(crate) encoder_t: syn::Path, pub(crate) fmt: syn::Path, pub(crate) option_none: syn::Path, pub(crate) option_some: syn::Path, pub(crate) pack_decoder_t: syn::Path, + pub(crate) pack_encoder_t: syn::Path, + pub(crate) result_err: syn::Path, + pub(crate) result_ok: syn::Path, pub(crate) struct_decoder_t: syn::Path, - pub(crate) struct_field_decoder_t: syn::Path, pub(crate) struct_encoder_t: syn::Path, + pub(crate) struct_field_decoder_t: syn::Path, pub(crate) struct_field_encoder_t: syn::Path, - pub(crate) result_err: syn::Path, - pub(crate) result_ok: syn::Path, - pub(crate) sequence_encoder_t: syn::Path, pub(crate) trace_decode_t: syn::Path, pub(crate) trace_encode_t: syn::Path, pub(crate) variant_decoder_t: syn::Path, @@ -57,7 +57,7 @@ impl Tokens { struct_field_encoder_t: path(span, prefix, ["en", "StructFieldEncoder"]), result_err: core(span, ["result", "Result", "Err"]), result_ok: core(span, ["result", "Result", "Ok"]), - sequence_encoder_t: path(span, prefix, ["en", "SequenceEncoder"]), + pack_encoder_t: path(span, prefix, ["en", "PackEncoder"]), trace_decode_t: path(span, prefix, ["de", "TraceDecode"]), trace_encode_t: path(span, prefix, ["en", "TraceEncode"]), variant_decoder_t: path(span, prefix, ["de", "VariantDecoder"]), diff --git a/crates/musli-macros/src/lib.rs b/crates/musli-macros/src/lib.rs index 93be0f7a1..d05704ee4 100644 --- a/crates/musli-macros/src/lib.rs +++ b/crates/musli-macros/src/lib.rs @@ -90,56 +90,6 @@ pub fn decoder(attr: TokenStream, input: TokenStream) -> TokenStream { } } -/// Please refer to the main [musli documentation](https://docs.rs/musli/). -#[proc_macro_attribute] -pub fn map_decoder(attr: TokenStream, input: TokenStream) -> TokenStream { - let attr = proc_macro2::TokenStream::from(attr); - - if !attr.is_empty() { - return syn::Error::new_spanned(attr, "Arguments not supported") - .to_compile_error() - .into(); - } - - let input = syn::parse_macro_input!(input as types::Types); - - match input.expand( - "map_decoder", - types::MAP_DECODER_TYPES, - None, - "__UseMusliMapDecoderAttributeMacro", - types::Kind::SelfCx, - ) { - Ok(tokens) => tokens.into(), - Err(err) => err.to_compile_error().into(), - } -} - -/// Please refer to the main [musli documentation](https://docs.rs/musli/). -#[proc_macro_attribute] -pub fn struct_decoder(attr: TokenStream, input: TokenStream) -> TokenStream { - let attr = proc_macro2::TokenStream::from(attr); - - if !attr.is_empty() { - return syn::Error::new_spanned(attr, "Arguments not supported") - .to_compile_error() - .into(); - } - - let input = syn::parse_macro_input!(input as types::Types); - - match input.expand( - "struct_decoder", - types::STRUCT_DECODER_TYPES, - None, - "__UseMusliStructDecoderAttributeMacro", - types::Kind::SelfCx, - ) { - Ok(tokens) => tokens.into(), - Err(err) => err.to_compile_error().into(), - } -} - /// Please refer to the main [musli documentation](https://docs.rs/musli/). #[proc_macro_attribute] pub fn encoder(attr: TokenStream, input: TokenStream) -> TokenStream { diff --git a/crates/musli-macros/src/types.rs b/crates/musli-macros/src/types.rs index d30542e34..d50342e67 100644 --- a/crates/musli-macros/src/types.rs +++ b/crates/musli-macros/src/types.rs @@ -54,14 +54,12 @@ pub(super) const DECODER_TYPES: &[(&str, Extra)] = &[ ("DecodeSequence", Extra::None), ("DecodeTuple", Extra::None), ("DecodeMap", Extra::None), + ("DecodeMapEntries", Extra::None), ("DecodeStruct", Extra::None), + ("DecodeStructFields", Extra::None), ("DecodeVariant", Extra::None), ]; -pub(super) const MAP_DECODER_TYPES: &[(&str, Extra)] = &[("IntoMapEntries", Extra::None)]; - -pub(super) const STRUCT_DECODER_TYPES: &[(&str, Extra)] = &[("IntoStructFields", Extra::None)]; - pub(super) const VISITOR_TYPES: &[(&str, Extra)] = &[ ("String", Extra::Visitor(Ty::Str)), ("Bytes", Extra::Visitor(Ty::Bytes)), diff --git a/crates/musli-serde/src/deserializer.rs b/crates/musli-serde/src/deserializer.rs index 6dbc7d588..3bfec0584 100644 --- a/crates/musli-serde/src/deserializer.rs +++ b/crates/musli-serde/src/deserializer.rs @@ -1,8 +1,8 @@ use core::fmt; use musli::de::{ - Decoder, MapDecoder, MapEntriesDecoder, PackDecoder, SequenceDecoder, SizeHint, StructDecoder, - StructFieldsDecoder, VariantDecoder, Visitor, + Decoder, MapDecoder, MapEntriesDecoder, SequenceDecoder, SizeHint, StructFieldsDecoder, + TupleDecoder, VariantDecoder, Visitor, }; use musli::Context; use serde::de; @@ -252,7 +252,7 @@ where V: de::Visitor<'de>, { self.decoder - .decode_sequence_fn(|d| visitor.visit_seq(SeqAccess::new(self.cx, d))) + .decode_sequence(|d| visitor.visit_seq(SeqAccess::new(self.cx, d))) } #[inline] @@ -260,7 +260,7 @@ where where V: de::Visitor<'de>, { - self.decoder.decode_tuple_fn(len, |d| { + self.decoder.decode_tuple(len, |d| { visitor.visit_seq(TupleAccess::new(self.cx, d, len)) }) } @@ -283,9 +283,9 @@ where where V: de::Visitor<'de>, { - let mut decoder = self.decoder.decode_map()?.into_map_entries()?; + let mut decoder = self.decoder.decode_map_entries()?; let output = visitor.visit_map(MapAccess::new(self.cx, &mut decoder))?; - decoder.end()?; + decoder.end_map_entries()?; Ok(output) } @@ -299,12 +299,9 @@ where where V: de::Visitor<'de>, { - let mut decoder = self - .decoder - .decode_struct(Some(fields.len()))? - .into_struct_fields()?; + let mut decoder = self.decoder.decode_struct_fields(Some(fields.len()))?; let output = visitor.visit_map(StructAccess::new(self.cx, &mut decoder, fields))?; - decoder.end()?; + decoder.end_struct_fields()?; Ok(output) } @@ -318,8 +315,8 @@ where where V: de::Visitor<'de>, { - let decoder = self.decoder.decode_variant()?; - visitor.visit_enum(EnumAccess::new(self.cx, decoder)) + self.decoder + .decode_variant(|decoder| visitor.visit_enum(EnumAccess::new(self.cx, decoder))) } #[inline] @@ -342,7 +339,7 @@ where struct TupleAccess<'de, 'a, D> where - D: PackDecoder<'de>, + D: TupleDecoder<'de>, { cx: &'a D::Cx, decoder: &'a mut D, @@ -351,7 +348,7 @@ where impl<'de, 'a, D> TupleAccess<'de, 'a, D> where - D: PackDecoder<'de>, + D: TupleDecoder<'de>, { fn new(cx: &'a D::Cx, decoder: &'a mut D, len: usize) -> Self { TupleAccess { @@ -364,7 +361,7 @@ where impl<'de, 'a, D> de::SeqAccess<'de> for TupleAccess<'de, 'a, D> where - D: PackDecoder<'de>, + D: TupleDecoder<'de>, ::Error: de::Error, { type Error = ::Error; @@ -750,14 +747,14 @@ where D: VariantDecoder<'de>, { cx: &'a D::Cx, - decoder: D, + decoder: &'a mut D, } impl<'de, 'a, D> EnumAccess<'de, 'a, D> where D: VariantDecoder<'de>, { - fn new(cx: &'a D::Cx, decoder: D) -> Self { + fn new(cx: &'a D::Cx, decoder: &'a mut D) -> Self { Self { cx, decoder } } } @@ -770,36 +767,31 @@ where type Error = ::Error; #[inline] - fn unit_variant(mut self) -> Result<(), Self::Error> { + fn unit_variant(self) -> Result<(), Self::Error> { self.decoder.decode_value()?.decode_unit() } #[inline] - fn newtype_variant_seed(mut self, seed: T) -> Result + fn newtype_variant_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { - let value = seed.deserialize(Deserializer::new(self.cx, self.decoder.decode_value()?))?; - self.decoder.end()?; - Ok(value) + seed.deserialize(Deserializer::new(self.cx, self.decoder.decode_value()?)) } #[inline] - fn tuple_variant(mut self, len: usize, visitor: V) -> Result + fn tuple_variant(self, len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { - let decoder = self.decoder.decode_value()?; - let value = decoder.decode_tuple_fn(len, |tuple| { + self.decoder.decode_value()?.decode_tuple(len, |tuple| { visitor.visit_seq(TupleAccess::new(self.cx, tuple, len)) - })?; - self.decoder.end()?; - Ok(value) + }) } #[inline] fn struct_variant( - mut self, + self, fields: &'static [&'static str], visitor: V, ) -> Result @@ -807,12 +799,9 @@ where V: de::Visitor<'de>, { let decoder = self.decoder.decode_value()?; - let mut st = decoder - .decode_struct(Some(fields.len()))? - .into_struct_fields()?; + let mut st = decoder.decode_struct_fields(Some(fields.len()))?; let value = visitor.visit_map(StructAccess::new(self.cx, &mut st, fields))?; - st.end()?; - self.decoder.end()?; + st.end_struct_fields()?; Ok(value) } } @@ -826,7 +815,7 @@ where type Variant = Self; #[inline] - fn variant_seed(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: de::DeserializeSeed<'de>, { @@ -981,25 +970,23 @@ where } #[inline] - fn visit_sequence(self, cx: &C, mut decoder: D) -> Result + fn visit_sequence(self, cx: &C, decoder: &mut D) -> Result where D: SequenceDecoder<'de, Cx = C>, { - let value = self.visitor.visit_seq(SeqAccess::new(cx, &mut decoder))?; - decoder.end()?; - Ok(value) + self.visitor.visit_seq(SeqAccess::new(cx, decoder)) } #[inline] - fn visit_map(self, cx: &C, decoder: D) -> Result + fn visit_map(self, cx: &C, decoder: &mut D) -> Result where D: MapDecoder<'de, Cx = C>, { - let mut map_decoder = decoder.into_map_entries()?; + let mut map_decoder = decoder.decode_remaining_entries()?; let value = self .visitor .visit_map(MapAccess::new(cx, &mut map_decoder))?; - map_decoder.end()?; + map_decoder.end_map_entries()?; Ok(value) } diff --git a/crates/musli-serde/src/serializer.rs b/crates/musli-serde/src/serializer.rs index 7c15faaa7..8daa60601 100644 --- a/crates/musli-serde/src/serializer.rs +++ b/crates/musli-serde/src/serializer.rs @@ -1,7 +1,8 @@ use core::fmt; use musli::en::{ - MapEntriesEncoder, SequenceEncoder, StructEncoder, StructFieldEncoder, VariantEncoder, + MapEntriesEncoder, SequenceEncoder, StructEncoder, StructFieldEncoder, TupleEncoder, + VariantEncoder, }; use musli::{Context, Encoder}; @@ -34,9 +35,9 @@ where type Error = ::Error; type SerializeSeq = SerializeSeq<'a, E::EncodeSequence>; - type SerializeTuple = SerializeSeq<'a, E::EncodeTuple>; + type SerializeTuple = SerializeTuple<'a, E::EncodeTuple>; type SerializeTupleStruct = SerializeTupleStruct<'a, E::EncodeStruct>; - type SerializeTupleVariant = SerializeSeq<'a, E::EncodeTupleVariant>; + type SerializeTupleVariant = SerializeTuple<'a, E::EncodeTupleVariant>; type SerializeMap = SerializeMap<'a, E::EncodeMapEntries>; type SerializeStruct = SerializeStruct<'a, E::EncodeStruct>; type SerializeStructVariant = SerializeStructVariant<'a, E::EncodeStructVariant>; @@ -200,7 +201,7 @@ where #[inline] fn serialize_tuple(self, len: usize) -> Result { let encoder = self.encoder.encode_tuple(len)?; - Ok(SerializeSeq::new(self.cx, encoder)) + Ok(SerializeTuple::new(self.cx, encoder)) } #[inline] @@ -222,7 +223,7 @@ where len: usize, ) -> Result { let encoder = self.encoder.encode_tuple_variant(variant_name, len)?; - Ok(SerializeSeq::new(self.cx, encoder)) + Ok(SerializeTuple::new(self.cx, encoder)) } #[inline] @@ -287,7 +288,7 @@ where let mut variant = encoder.encode_variant()?; variant_tag.serialize(Serializer::new(cx, variant.encode_tag()?))?; let output = f(variant.encode_value()?)?; - variant.end()?; + variant.end_variant()?; Ok(output) } @@ -321,21 +322,38 @@ where where T: ser::Serialize, { - let encoder = self.encoder.encode_next()?; + let encoder = self.encoder.encode_element()?; value.serialize(Serializer::new(self.cx, encoder))?; Ok(()) } #[inline] fn end(self) -> Result { - self.encoder.end() + self.encoder.end_sequence() } } -impl<'a, E> ser::SerializeTuple for SerializeSeq<'a, E> +pub struct SerializeTuple<'a, E> +where + E: TupleEncoder, +{ + cx: &'a E::Cx, + encoder: E, +} + +impl<'a, E> SerializeTuple<'a, E> +where + E: TupleEncoder, +{ + fn new(cx: &'a E::Cx, encoder: E) -> Self { + Self { cx, encoder } + } +} + +impl<'a, E> ser::SerializeTuple for SerializeTuple<'a, E> where ::Error: ser::Error, - E: SequenceEncoder, + E: TupleEncoder, { type Ok = E::Ok; type Error = ::Error; @@ -345,19 +363,21 @@ where where T: ser::Serialize, { - ser::SerializeSeq::serialize_element(self, value) + let encoder = self.encoder.encode_tuple_field()?; + value.serialize(Serializer::new(self.cx, encoder))?; + Ok(()) } #[inline] fn end(self) -> Result { - ser::SerializeSeq::end(self) + self.encoder.end_tuple() } } -impl<'a, E> ser::SerializeTupleVariant for SerializeSeq<'a, E> +impl<'a, E> ser::SerializeTupleVariant for SerializeTuple<'a, E> where ::Error: ser::Error, - E: SequenceEncoder, + E: TupleEncoder, { type Ok = E::Ok; type Error = ::Error; @@ -367,12 +387,12 @@ where where T: ser::Serialize, { - ser::SerializeSeq::serialize_element(self, value) + ser::SerializeTuple::serialize_element(self, value) } #[inline] fn end(self) -> Result { - ser::SerializeSeq::end(self) + ser::SerializeTuple::end(self) } } @@ -411,7 +431,7 @@ where where T: ser::Serialize, { - self.encoder.encode_field_fn(|field| { + self.encoder.encode_struct_field_fn(|field| { field.encode_field_name()?.encode(self.field)?; value.serialize(Serializer::new(self.cx, field.encode_field_value()?))?; Ok(()) @@ -420,7 +440,7 @@ where #[inline] fn end(self) -> Result { - self.encoder.end() + self.encoder.end_struct() } } @@ -471,7 +491,7 @@ where #[inline] fn end(self) -> Result { - self.encoder.end() + self.encoder.end_map_entries() } } @@ -509,16 +529,16 @@ where where T: ser::Serialize, { - let mut field = self.encoder.encode_field()?; + let mut field = self.encoder.encode_struct_field()?; field.encode_field_name()?.encode(key)?; value.serialize(Serializer::new(self.cx, field.encode_field_value()?))?; - field.end()?; + field.end_field()?; Ok(()) } #[inline] fn end(self) -> Result { - self.encoder.end() + self.encoder.end_struct() } } @@ -556,7 +576,7 @@ where where T: ser::Serialize, { - self.encoder.encode_field_fn(|field| { + self.encoder.encode_struct_field_fn(|field| { field.encode_field_name()?.encode(key)?; value.serialize(Serializer::new(self.cx, field.encode_field_value()?))?; Ok(()) @@ -565,6 +585,6 @@ where #[inline] fn end(self) -> Result { - self.encoder.end() + self.encoder.end_struct() } } diff --git a/crates/musli-storage/src/de.rs b/crates/musli-storage/src/de.rs index 98bdbe42a..28481d60e 100644 --- a/crates/musli-storage/src/de.rs +++ b/crates/musli-storage/src/de.rs @@ -5,7 +5,8 @@ use alloc::vec::Vec; use musli::de::{ Decoder, MapDecoder, MapEntriesDecoder, MapEntryDecoder, PackDecoder, SequenceDecoder, - SizeHint, StructDecoder, StructFieldDecoder, StructFieldsDecoder, ValueVisitor, VariantDecoder, + SizeHint, StructDecoder, StructFieldDecoder, StructFieldsDecoder, TupleDecoder, ValueVisitor, + VariantDecoder, }; use musli::{Context, Decode}; @@ -13,12 +14,12 @@ use crate::options::Options; use crate::reader::Reader; /// A very simple decoder suitable for storage decoding. -pub struct StorageDecoder<'a, R, const F: Options, C: ?Sized> { +pub struct StorageDecoder<'a, R, const OPT: Options, C: ?Sized> { cx: &'a C, reader: R, } -impl<'a, R, const F: Options, C: ?Sized> StorageDecoder<'a, R, F, C> { +impl<'a, R, const OPT: Options, C: ?Sized> StorageDecoder<'a, R, OPT, C> { /// Construct a new fixed width message encoder. #[inline] pub fn new(cx: &'a C, reader: R) -> Self { @@ -31,26 +32,30 @@ impl<'a, R, const F: Options, C: ?Sized> StorageDecoder<'a, R, F, C> { /// This simplifies implementing decoders that do not have any special handling /// for length-prefixed types. #[doc(hidden)] -pub struct LimitedStorageDecoder<'a, R, const F: Options, C: ?Sized> { +pub struct LimitedStorageDecoder<'a, R, const OPT: Options, C: ?Sized> { remaining: usize, - decoder: StorageDecoder<'a, R, F, C>, + cx: &'a C, + reader: R, } #[musli::decoder] -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> Decoder<'de> for StorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> Decoder<'de> + for StorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; type Error = C::Error; type Mode = C::Mode; - type WithContext<'this, U> = StorageDecoder<'this, R, F, U> where U: 'this + Context; + type WithContext<'this, U> = StorageDecoder<'this, R, OPT, U> where U: 'this + Context; type DecodePack = Self; type DecodeSome = Self; - type DecodeSequence = LimitedStorageDecoder<'a, R, F, C>; + type DecodeSequence = LimitedStorageDecoder<'a, R, OPT, C>; type DecodeTuple = Self; - type DecodeMap = LimitedStorageDecoder<'a, R, F, C>; - type DecodeStruct = LimitedStorageDecoder<'a, R, F, C>; + type DecodeMap = LimitedStorageDecoder<'a, R, OPT, C>; + type DecodeMapEntries = LimitedStorageDecoder<'a, R, OPT, C>; + type DecodeStruct = LimitedStorageDecoder<'a, R, OPT, C>; + type DecodeStructFields = LimitedStorageDecoder<'a, R, OPT, C>; type DecodeVariant = Self; fn cx(&self) -> &C { @@ -81,7 +86,8 @@ where #[inline] fn decode_unit(mut self) -> Result<(), C::Error> { let mark = self.cx.mark(); - let count = musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())?; + let count = + musli_common::int::decode_usize::<_, _, OPT>(self.cx, self.reader.borrow_mut())?; if count != 0 { return Err(self @@ -93,8 +99,11 @@ where } #[inline] - fn decode_pack(self) -> Result { - Ok(self) + fn decode_pack(mut self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodePack) -> Result, + { + f(&mut self) } #[inline] @@ -107,7 +116,7 @@ where where V: ValueVisitor<'de, C, [u8]>, { - let len = musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())?; + let len = musli_common::int::decode_usize::<_, _, OPT>(self.cx, self.reader.borrow_mut())?; self.reader.read_bytes(self.cx, len, visitor) } @@ -184,22 +193,22 @@ where #[inline] fn decode_u16(self) -> Result { - musli_common::int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_u32(self) -> Result { - musli_common::int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_u64(self) -> Result { - musli_common::int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_u128(self) -> Result { - musli_common::int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] @@ -209,27 +218,27 @@ where #[inline] fn decode_i16(self) -> Result { - musli_common::int::decode_signed::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_i32(self) -> Result { - musli_common::int::decode_signed::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_i64(self) -> Result { - musli_common::int::decode_signed::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_i128(self) -> Result { - musli_common::int::decode_signed::<_, _, _, F>(self.cx, self.reader) + musli_common::int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_usize(self) -> Result { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader) + musli_common::int::decode_usize::<_, _, OPT>(self.cx, self.reader) } #[inline] @@ -259,70 +268,140 @@ where } #[inline] - fn decode_sequence(self) -> Result { - LimitedStorageDecoder::new(self) + fn decode_sequence(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeSequence) -> Result, + { + let cx = self.cx; + let mut decoder = LimitedStorageDecoder::new(self.cx, self.reader)?; + let output = f(&mut decoder)?; + + if decoder.remaining != 0 { + return Err(cx.message("Caller did not decode all available map entries")); + } + + Ok(output) } #[inline] - fn decode_tuple(self, _: usize) -> Result { - Ok(self) + fn decode_tuple(mut self, _: usize, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeTuple) -> Result, + { + f(&mut self) } #[inline] - fn decode_map(self) -> Result { - LimitedStorageDecoder::new(self) + fn decode_map(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeMap) -> Result, + { + let cx = self.cx; + let mut decoder = LimitedStorageDecoder::new(self.cx, self.reader)?; + let output = f(&mut decoder)?; + + if decoder.remaining != 0 { + return Err(cx.message("Caller did not decode all available map entries")); + } + + Ok(output) } #[inline] - fn decode_struct(self, _: Option) -> Result { - LimitedStorageDecoder::new(self) + fn decode_map_entries(self) -> Result { + LimitedStorageDecoder::new(self.cx, self.reader) } #[inline] - fn decode_variant(self) -> Result { - Ok(self) + fn decode_struct(self, _: Option, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeStruct) -> Result, + { + let cx = self.cx; + let mut decoder = LimitedStorageDecoder::new(self.cx, self.reader)?; + let output = f(&mut decoder)?; + + if decoder.remaining != 0 { + return Err(cx.message("Caller did not decode all available struct fields")); + } + + Ok(output) + } + + #[inline] + fn decode_struct_fields(self, _: Option) -> Result { + LimitedStorageDecoder::new(self.cx, self.reader) + } + + #[inline] + fn decode_variant(mut self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeVariant) -> Result, + { + f(&mut self) } } -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> PackDecoder<'de> - for StorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> PackDecoder<'de> + for StorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeNext<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeNext<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_next(&mut self) -> Result, C::Error> { Ok(StorageDecoder::new(self.cx, self.reader.borrow_mut())) } +} + +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> TupleDecoder<'de> + for StorageDecoder<'a, R, OPT, C> +where + R: Reader<'de>, +{ + type Cx = C; + type DecodeNext<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) + fn decode_next(&mut self) -> Result, C::Error> { + PackDecoder::decode_next(self) } } -impl<'a, 'de, R, const F: Options, C> LimitedStorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> LimitedStorageDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { #[inline] - fn new(mut decoder: StorageDecoder<'a, R, F, C>) -> Result { - let remaining = - musli_common::int::decode_usize::<_, _, F>(decoder.cx, &mut decoder.reader)?; - Ok(Self { remaining, decoder }) + fn new(cx: &'a C, mut reader: R) -> Result { + let remaining = musli_common::int::decode_usize::<_, _, OPT>(cx, reader.borrow_mut())?; + Ok(Self { + cx, + reader, + remaining, + }) + } + + #[inline] + fn with_remaining(cx: &'a C, reader: R, remaining: usize) -> Self { + Self { + cx, + reader, + remaining, + } } } -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> SequenceDecoder<'de> - for LimitedStorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> SequenceDecoder<'de> + for LimitedStorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeNext<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeNext<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { @@ -337,40 +416,26 @@ where self.remaining -= 1; - Ok(Some(StorageDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(StorageDecoder::new(self.cx, self.reader.borrow_mut()))) } } -#[musli::map_decoder] -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> MapDecoder<'de> - for LimitedStorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> MapDecoder<'de> + for LimitedStorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeEntry<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> + type DecodeEntry<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type IntoMapEntries = Self; - - #[inline] - fn cx(&self) -> &C { - self.decoder.cx - } + type DecodeRemainingEntries<'this> = LimitedStorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { SizeHint::Exact(self.remaining) } - #[inline] - fn into_map_entries(self) -> Result { - Ok(self) - } - #[inline] fn decode_entry(&mut self) -> Result>, C::Error> { if self.remaining == 0 { @@ -378,20 +443,28 @@ where } self.remaining -= 1; - Ok(Some(StorageDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(StorageDecoder::new(self.cx, self.reader.borrow_mut()))) + } + + #[inline] + fn decode_remaining_entries( + &mut self, + ) -> Result, ::Error> { + Ok(LimitedStorageDecoder::with_remaining( + self.cx, + self.reader.borrow_mut(), + self.remaining, + )) } } -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> MapEntryDecoder<'de> - for StorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> MapEntryDecoder<'de> + for StorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeMapKey<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeMapKey<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; type DecodeMapValue = Self; #[inline] @@ -410,52 +483,34 @@ where } } -#[musli::struct_decoder] -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> StructDecoder<'de> - for LimitedStorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> StructDecoder<'de> + for LimitedStorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeField<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> + type DecodeField<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type IntoStructFields = Self; - - #[inline] - fn cx(&self) -> &C { - self.decoder.cx - } - #[inline] fn size_hint(&self) -> SizeHint { MapDecoder::size_hint(self) } - #[inline] - fn into_struct_fields(self) -> Result { - Ok(self) - } - #[inline] fn decode_field(&mut self) -> Result>, C::Error> { MapDecoder::decode_entry(self) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - MapDecoder::end(self) - } } -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> StructFieldDecoder<'de> - for StorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> StructFieldDecoder<'de> + for StorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeFieldName<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeFieldName<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; type DecodeFieldValue = Self; #[inline] @@ -474,14 +529,14 @@ where } } -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> MapEntriesDecoder<'de> - for LimitedStorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> MapEntriesDecoder<'de> + for LimitedStorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeMapEntryKey<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; - type DecodeMapEntryValue<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeMapEntryKey<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; + type DecodeMapEntryValue<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_map_entry_key(&mut self) -> Result>, C::Error> { @@ -490,57 +545,53 @@ where } self.remaining -= 1; - Ok(Some(StorageDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(StorageDecoder::new(self.cx, self.reader.borrow_mut()))) } #[inline] fn decode_map_entry_value(&mut self) -> Result, C::Error> { - Ok(StorageDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + Ok(StorageDecoder::new(self.cx, self.reader.borrow_mut())) } #[inline] fn skip_map_entry_value(&mut self) -> Result { Ok(false) } + + #[inline] + fn end_map_entries(self) -> Result<(), C::Error> { + if self.remaining != 0 { + return Err(self + .cx + .message("Caller did not decode all available map entries")); + } + + Ok(()) + } } -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> StructFieldsDecoder<'de> - for LimitedStorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> StructFieldsDecoder<'de> + for LimitedStorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeStructFieldName<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; - type DecodeStructFieldValue<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeStructFieldName<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; + type DecodeStructFieldValue<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_struct_field_name(&mut self) -> Result, C::Error> { if self.remaining == 0 { - return Err(self - .decoder - .cx - .message("Ran out of struct fields to decode")); + return Err(self.cx.message("Ran out of struct fields to decode")); } self.remaining -= 1; - Ok(StorageDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + Ok(StorageDecoder::new(self.cx, self.reader.borrow_mut())) } #[inline] fn decode_struct_field_value(&mut self) -> Result, C::Error> { - Ok(StorageDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + Ok(StorageDecoder::new(self.cx, self.reader.borrow_mut())) } #[inline] @@ -549,19 +600,19 @@ where } #[inline] - fn end(self) -> Result<(), C::Error> { + fn end_struct_fields(self) -> Result<(), C::Error> { Ok(()) } } -impl<'a, 'de, R, const F: Options, C: ?Sized + Context> VariantDecoder<'de> - for StorageDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C: ?Sized + Context> VariantDecoder<'de> + for StorageDecoder<'a, R, OPT, C> where R: Reader<'de>, { type Cx = C; - type DecodeTag<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; - type DecodeValue<'this> = StorageDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeTag<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; + type DecodeValue<'this> = StorageDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_tag(&mut self) -> Result, C::Error> { @@ -577,11 +628,6 @@ where fn skip_value(&mut self) -> Result { Ok(false) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) - } } struct ExpectedEmptySequence { diff --git a/crates/musli-storage/src/en.rs b/crates/musli-storage/src/en.rs index fc1b741b9..09a0c518a 100644 --- a/crates/musli-storage/src/en.rs +++ b/crates/musli-storage/src/en.rs @@ -1,26 +1,21 @@ use core::fmt; use musli::en::{ - Encode, Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, SequenceEncoder, - StructEncoder, StructFieldEncoder, VariantEncoder, + Encode, Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, PackEncoder, SequenceEncoder, + StructEncoder, StructFieldEncoder, TupleEncoder, VariantEncoder, }; use musli::Context; -use crate::options::{self, Options}; +use crate::options::Options; use crate::writer::Writer; -const DEFAULT_OPTIONS: options::Options = options::new().build(); - -/// The alias for a [StorageEncoder] that is used for packs. -pub type PackEncoder<'a, W, C> = StorageEncoder<'a, W, DEFAULT_OPTIONS, C>; - /// A vaery simple encoder suitable for storage encoding. -pub struct StorageEncoder<'a, W, const F: Options, C: ?Sized> { +pub struct StorageEncoder<'a, W, const OPT: Options, C: ?Sized> { cx: &'a C, writer: W, } -impl<'a, W, const F: Options, C: ?Sized> StorageEncoder<'a, W, F, C> { +impl<'a, W, const OPT: Options, C: ?Sized> StorageEncoder<'a, W, OPT, C> { /// Construct a new fixed width message encoder. #[inline] pub fn new(cx: &'a C, writer: W) -> Self { @@ -29,7 +24,7 @@ impl<'a, W, const F: Options, C: ?Sized> StorageEncoder<'a, W, F, C> { } #[musli::encoder] -impl<'a, W, const F: Options, C> Encoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> Encoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, @@ -38,8 +33,8 @@ where type Error = C::Error; type Ok = (); type Mode = C::Mode; - type WithContext<'this, U> = StorageEncoder<'this, W, F, U> where U: 'this + Context; - type EncodePack = StorageEncoder<'a, W, F, C>; + type WithContext<'this, U> = StorageEncoder<'this, W, OPT, U> where U: 'this + Context; + type EncodePack = StorageEncoder<'a, W, OPT, C>; type EncodeSome = Self; type EncodeSequence = Self; type EncodeTuple = Self; @@ -78,7 +73,7 @@ where #[inline] fn encode_unit(self) -> Result { - SequenceEncoder::end(self.encode_sequence(0)?) + self.encode_sequence_fn(0, |_| Ok(())) } #[inline] @@ -93,7 +88,11 @@ where #[inline] fn encode_bytes(mut self, bytes: &[u8]) -> Result { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), bytes.len())?; + musli_common::int::encode_usize::<_, _, OPT>( + self.cx, + self.writer.borrow_mut(), + bytes.len(), + )?; self.writer.write_bytes(self.cx, bytes)?; Ok(()) } @@ -104,7 +103,7 @@ where I: IntoIterator, I::Item: AsRef<[u8]>, { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; for bytes in vectors { self.writer.write_bytes(self.cx, bytes.as_ref())?; @@ -115,7 +114,7 @@ where #[inline] fn encode_string(mut self, string: &str) -> Result { - musli_common::int::encode_usize::<_, _, F>( + musli_common::int::encode_usize::<_, _, OPT>( self.cx, self.writer.borrow_mut(), string.len(), @@ -135,7 +134,7 @@ where #[inline] fn encode_usize(mut self, value: usize) -> Result { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] @@ -160,22 +159,22 @@ where #[inline] fn encode_u16(mut self, value: u16) -> Result { - musli_common::int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_u32(mut self, value: u32) -> Result { - musli_common::int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_u64(mut self, value: u64) -> Result { - musli_common::int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_u128(mut self, value: u128) -> Result { - musli_common::int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] @@ -185,22 +184,22 @@ where #[inline] fn encode_i16(mut self, value: i16) -> Result { - musli_common::int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_i32(mut self, value: i32) -> Result { - musli_common::int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_i64(mut self, value: i64) -> Result { - musli_common::int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_i128(mut self, value: i128) -> Result { - musli_common::int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + musli_common::int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] @@ -227,7 +226,7 @@ where #[inline] fn encode_sequence(mut self, len: usize) -> Result { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; Ok(self) } @@ -239,19 +238,19 @@ where #[inline] fn encode_map(mut self, len: usize) -> Result { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; Ok(self) } #[inline] fn encode_map_entries(mut self, len: usize) -> Result { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; Ok(self) } #[inline] fn encode_struct(mut self, len: usize) -> Result { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; Ok(self) } @@ -269,7 +268,7 @@ where where T: ?Sized + Encode, { - StorageEncoder::<_, F, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; + StorageEncoder::<_, OPT, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; Ok(self) } @@ -282,61 +281,101 @@ where where T: ?Sized + Encode, { - StorageEncoder::<_, F, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + StorageEncoder::<_, OPT, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; Ok(self) } } -impl<'a, W, const F: Options, C> SequenceEncoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> PackEncoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeNext<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodePacked<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_packed(&mut self) -> Result, C::Error> { Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut())) } #[inline] - fn end(self) -> Result { + fn end_pack(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEncoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> SequenceEncoder for StorageEncoder<'a, W, OPT, C> +where + C: ?Sized + Context, + W: Writer, +{ + type Cx = C; + type Ok = (); + type EncodeElement<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + + #[inline] + fn encode_element(&mut self) -> Result, C::Error> { + PackEncoder::encode_packed(self) + } + + #[inline] + fn end_sequence(self) -> Result { + PackEncoder::end_pack(self) + } +} + +impl<'a, W, const OPT: Options, C> TupleEncoder for StorageEncoder<'a, W, OPT, C> +where + C: ?Sized + Context, + W: Writer, +{ + type Cx = C; + type Ok = (); + type EncodeTupleField<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + + #[inline] + fn encode_tuple_field(&mut self) -> Result, C::Error> { + PackEncoder::encode_packed(self) + } + + #[inline] + fn end_tuple(self) -> Result { + PackEncoder::end_pack(self) + } +} + +impl<'a, W, const OPT: Options, C> MapEncoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeEntry<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapEntry<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_entry(&mut self) -> Result, C::Error> { + fn encode_map_entry(&mut self) -> Result, C::Error> { Ok(StorageEncoder::new(self.cx, self.writer.borrow_mut())) } #[inline] - fn end(self) -> Result { + fn end_map(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEntryEncoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> MapEntryEncoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeMapKey<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeMapValue<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapKey<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeMapValue<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_map_key(&mut self) -> Result, C::Error> { @@ -349,20 +388,20 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entry(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEntriesEncoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> MapEntriesEncoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeMapEntryKey<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeMapEntryValue<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapEntryKey<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeMapEntryValue<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_map_entry_key(&mut self) -> Result, C::Error> { @@ -375,40 +414,40 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entries(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> StructEncoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> StructEncoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeField<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeStructField<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_field(&mut self) -> Result, C::Error> { - MapEncoder::encode_entry(self) + fn encode_struct_field(&mut self) -> Result, C::Error> { + MapEncoder::encode_map_entry(self) } #[inline] - fn end(self) -> Result { + fn end_struct(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> StructFieldEncoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> StructFieldEncoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeFieldName<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeFieldValue<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeFieldName<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeFieldValue<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_field_name(&mut self) -> Result, C::Error> { @@ -421,20 +460,20 @@ where } #[inline] - fn end(self) -> Result { - MapEntryEncoder::end(self) + fn end_field(self) -> Result { + MapEntryEncoder::end_map_entry(self) } } -impl<'a, W, const F: Options, C> VariantEncoder for StorageEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> VariantEncoder for StorageEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeTag<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeValue<'this> = StorageEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeTag<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeValue<'this> = StorageEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_tag(&mut self) -> Result, C::Error> { @@ -447,7 +486,7 @@ where } #[inline] - fn end(self) -> Result { + fn end_variant(self) -> Result { Ok(()) } } diff --git a/crates/musli-storage/src/encoding.rs b/crates/musli-storage/src/encoding.rs index de9990cb8..d6125c2bf 100644 --- a/crates/musli-storage/src/encoding.rs +++ b/crates/musli-storage/src/encoding.rs @@ -99,7 +99,7 @@ where } /// Setting up encoding with parameters. -pub struct Encoding { +pub struct Encoding { _marker: marker::PhantomData, } @@ -144,9 +144,9 @@ impl Encoding { } } -impl Encoding { +impl Encoding { /// Change the mode of the encoding. - pub const fn with_mode(self) -> Encoding { + pub const fn with_mode(self) -> Encoding { Encoding { _marker: marker::PhantomData, } @@ -172,17 +172,17 @@ impl Encoding { musli_common::encoding_impls!( M, - StorageEncoder::<_, F, _>::new, - StorageDecoder::<_, F, _>::new + StorageEncoder::<_, OPT, _>::new, + StorageDecoder::<_, OPT, _>::new ); musli_common::encoding_from_slice_impls!(M, StorageDecoder::<_, F>::new); } -impl Clone for Encoding { +impl Clone for Encoding { #[inline] fn clone(&self) -> Self { *self } } -impl Copy for Encoding {} +impl Copy for Encoding {} diff --git a/crates/musli-value/src/de.rs b/crates/musli-value/src/de.rs index 4bac876f4..932153ab4 100644 --- a/crates/musli-value/src/de.rs +++ b/crates/musli-value/src/de.rs @@ -6,7 +6,7 @@ use musli::de::ValueVisitor; use musli::de::{ AsDecoder, Decode, Decoder, MapDecoder, MapEntriesDecoder, MapEntryDecoder, NumberHint, PackDecoder, SequenceDecoder, SizeHint, StructDecoder, StructFieldDecoder, StructFieldsDecoder, - TypeHint, VariantDecoder, Visitor, + TupleDecoder, TypeHint, VariantDecoder, Visitor, }; use musli::Context; use musli_storage::de::StorageDecoder; @@ -18,12 +18,12 @@ use crate::value::{Number, Value}; use crate::AsValueDecoder; /// Encoder for a single value. -pub struct ValueDecoder<'a, 'de, const F: Options, C: ?Sized> { +pub struct ValueDecoder<'a, 'de, const OPT: Options, C: ?Sized> { cx: &'a C, value: &'de Value, } -impl<'a, 'de, const F: Options, C: ?Sized> ValueDecoder<'a, 'de, F, C> { +impl<'a, 'de, const OPT: Options, C: ?Sized> ValueDecoder<'a, 'de, OPT, C> { #[inline] pub(crate) const fn new(cx: &'a C, value: &'de Value) -> Self { Self { cx, value } @@ -43,19 +43,23 @@ macro_rules! ensure { } #[musli::decoder] -impl<'a, 'de, C: ?Sized + Context, const F: Options> Decoder<'de> for ValueDecoder<'a, 'de, F, C> { +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> Decoder<'de> + for ValueDecoder<'a, 'de, OPT, C> +{ type Cx = C; type Error = C::Error; type Mode = C::Mode; - type WithContext<'this, U> = ValueDecoder<'this, 'de, F, U> where U: 'this + Context; - type DecodeBuffer = AsValueDecoder<'a, F, C>; + type WithContext<'this, U> = ValueDecoder<'this, 'de, OPT, U> where U: 'this + Context; + type DecodeBuffer = AsValueDecoder<'a, OPT, C>; type DecodeSome = Self; - type DecodePack = StorageDecoder<'a, SliceReader<'de>, F, C>; - type DecodeSequence = IterValueDecoder<'a, 'de, F, C>; - type DecodeTuple = IterValueDecoder<'a, 'de, F, C>; - type DecodeMap = IterValuePairsDecoder<'a, 'de, F, C>; - type DecodeStruct = IterValuePairsDecoder<'a, 'de, F, C>; - type DecodeVariant = IterValueVariantDecoder<'a, 'de, F, C>; + type DecodePack = StorageDecoder<'a, SliceReader<'de>, OPT, C>; + type DecodeSequence = IterValueDecoder<'a, 'de, OPT, C>; + type DecodeTuple = IterValueDecoder<'a, 'de, OPT, C>; + type DecodeMap = IterValuePairsDecoder<'a, 'de, OPT, C>; + type DecodeMapEntries = IterValuePairsDecoder<'a, 'de, OPT, C>; + type DecodeStruct = IterValuePairsDecoder<'a, 'de, OPT, C>; + type DecodeStructFields = IterValuePairsDecoder<'a, 'de, OPT, C>; + type DecodeVariant = IterValueVariantDecoder<'a, 'de, OPT, C>; #[inline] fn cx(&self) -> &Self::Cx { @@ -242,31 +246,51 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> Decoder<'de> for ValueDecod #[cfg(feature = "alloc")] #[inline] - fn decode_pack(self) -> Result { + fn decode_pack(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodePack) -> Result, + { ensure!(self, hint, ExpectedPack(hint), Value::Bytes(pack) => { - Ok(StorageDecoder::new(self.cx, SliceReader::new(pack))) + f(&mut StorageDecoder::new(self.cx, SliceReader::new(pack))) }) } #[cfg(feature = "alloc")] #[inline] - fn decode_sequence(self) -> Result { + fn decode_sequence(self, f: F) -> Result::Error> + where + F: FnOnce(&mut Self::DecodeSequence) -> Result::Error>, + { ensure!(self, hint, ExpectedSequence(hint), Value::Sequence(sequence) => { - Ok(IterValueDecoder::new(self.cx, sequence)) + f(&mut IterValueDecoder::new(self.cx, sequence)) }) } #[cfg(feature = "alloc")] #[inline] - fn decode_tuple(self, _: usize) -> Result { + fn decode_tuple(self, _: usize, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeTuple) -> Result, + { ensure!(self, hint, ExpectedSequence(hint), Value::Sequence(sequence) => { - Ok(IterValueDecoder::new(self.cx, sequence)) + f(&mut IterValueDecoder::new(self.cx, sequence)) }) } #[cfg(feature = "alloc")] #[inline] - fn decode_map(self) -> Result { + fn decode_map(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeMap) -> Result, + { + ensure!(self, hint, ExpectedMap(hint), Value::Map(map) => { + f(&mut IterValuePairsDecoder::new(self.cx, map)) + }) + } + + #[cfg(feature = "alloc")] + #[inline] + fn decode_map_entries(self) -> Result { ensure!(self, hint, ExpectedMap(hint), Value::Map(map) => { Ok(IterValuePairsDecoder::new(self.cx, map)) }) @@ -274,7 +298,18 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> Decoder<'de> for ValueDecod #[cfg(feature = "alloc")] #[inline] - fn decode_struct(self, _: Option) -> Result { + fn decode_struct(self, _: Option, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeStruct) -> Result, + { + ensure!(self, hint, ExpectedMap(hint), Value::Map(st) => { + f(&mut IterValuePairsDecoder::new(self.cx, st)) + }) + } + + #[cfg(feature = "alloc")] + #[inline] + fn decode_struct_fields(self, _: Option) -> Result { ensure!(self, hint, ExpectedMap(hint), Value::Map(st) => { Ok(IterValuePairsDecoder::new(self.cx, st)) }) @@ -282,9 +317,12 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> Decoder<'de> for ValueDecod #[cfg(feature = "alloc")] #[inline] - fn decode_variant(self) -> Result { + fn decode_variant(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeVariant) -> Result, + { ensure!(self, hint, ExpectedVariant(hint), Value::Variant(st) => { - Ok(IterValueVariantDecoder::new(self.cx, st)) + f(&mut IterValueVariantDecoder::new(self.cx, st)) }) } @@ -324,32 +362,34 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> Decoder<'de> for ValueDecod visitor.visit_borrowed(self.cx, string) } #[cfg(feature = "alloc")] - Value::Sequence(values) => { - visitor.visit_sequence(self.cx, IterValueDecoder::::new(self.cx, values)) - } + Value::Sequence(values) => visitor.visit_sequence( + self.cx, + &mut IterValueDecoder::::new(self.cx, values), + ), #[cfg(feature = "alloc")] - Value::Map(values) => { - visitor.visit_map(self.cx, IterValuePairsDecoder::::new(self.cx, values)) - } + Value::Map(values) => visitor.visit_map( + self.cx, + &mut IterValuePairsDecoder::::new(self.cx, values), + ), #[cfg(feature = "alloc")] Value::Variant(variant) => visitor.visit_variant( self.cx, - IterValueVariantDecoder::::new(self.cx, variant), + &mut IterValueVariantDecoder::::new(self.cx, variant), ), #[cfg(feature = "alloc")] Value::Option(option) => visitor.visit_option( self.cx, option .as_ref() - .map(|value| ValueDecoder::::new(self.cx, value)), + .map(|value| ValueDecoder::::new(self.cx, value)), ), } } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> AsDecoder for ValueDecoder<'a, 'de, F, C> { +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> AsDecoder for ValueDecoder<'a, 'de, OPT, C> { type Cx = C; - type Decoder<'this> = ValueDecoder<'a, 'this, F, C> where Self: 'this; + type Decoder<'this> = ValueDecoder<'a, 'this, OPT, C> where Self: 'this; #[inline] fn as_decoder(&self) -> Result, C::Error> { @@ -359,13 +399,13 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> AsDecoder for ValueDecoder< /// A decoder over a simple value iterator. -pub struct IterValueDecoder<'a, 'de, const F: Options, C: ?Sized> { +pub struct IterValueDecoder<'a, 'de, const OPT: Options, C: ?Sized> { cx: &'a C, iter: slice::Iter<'de, Value>, } #[cfg(feature = "alloc")] -impl<'a, 'de, const F: Options, C: ?Sized> IterValueDecoder<'a, 'de, F, C> { +impl<'a, 'de, const OPT: Options, C: ?Sized> IterValueDecoder<'a, 'de, OPT, C> { #[inline] fn new(cx: &'a C, values: &'de [Value]) -> Self { Self { @@ -375,11 +415,11 @@ impl<'a, 'de, const F: Options, C: ?Sized> IterValueDecoder<'a, 'de, F, C> { } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> PackDecoder<'de> - for IterValueDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> PackDecoder<'de> + for IterValueDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeNext<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeNext<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; @@ -390,18 +430,27 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> PackDecoder<'de> None => Err(self.cx.message(ErrorMessage::ExpectedPackValue)), } } +} + +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> TupleDecoder<'de> + for IterValueDecoder<'a, 'de, OPT, C> +{ + type Cx = C; + type DecodeNext<'this> = ValueDecoder<'a, 'de, OPT, C> + where + Self: 'this; #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) + fn decode_next(&mut self) -> Result, C::Error> { + PackDecoder::decode_next(self) } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> SequenceDecoder<'de> - for IterValueDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> SequenceDecoder<'de> + for IterValueDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeNext<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeNext<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; @@ -417,21 +466,15 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> SequenceDecoder<'de> None => Ok(None), } } - - #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) - } } /// A decoder over a simple value pair iterator. -pub struct IterValuePairsDecoder<'a, 'de, const F: Options, C: ?Sized> { +pub struct IterValuePairsDecoder<'a, 'de, const OPT: Options, C: ?Sized> { cx: &'a C, iter: slice::Iter<'de, (Value, Value)>, } -#[cfg(feature = "alloc")] -impl<'a, 'de, const F: Options, C: ?Sized> IterValuePairsDecoder<'a, 'de, F, C> { +impl<'a, 'de, const OPT: Options, C: ?Sized> IterValuePairsDecoder<'a, 'de, OPT, C> { #[inline] fn new(cx: &'a C, values: &'de [(Value, Value)]) -> Self { Self { @@ -441,31 +484,20 @@ impl<'a, 'de, const F: Options, C: ?Sized> IterValuePairsDecoder<'a, 'de, F, C> } } -#[musli::map_decoder] -impl<'a, 'de, C: ?Sized + Context, const F: Options> MapDecoder<'de> - for IterValuePairsDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> MapDecoder<'de> + for IterValuePairsDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeEntry<'this> = IterValuePairDecoder<'a, 'de, F, C> + type DecodeEntry<'this> = IterValuePairDecoder<'a, 'de, OPT, C> where Self: 'this; - type IntoMapEntries = Self; - - #[inline] - fn cx(&self) -> &Self::Cx { - self.cx - } + type DecodeRemainingEntries<'this> = IterValuePairsDecoder<'a, 'de, OPT, C> where Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { SizeHint::from(self.iter.size_hint().1) } - #[inline] - fn into_map_entries(self) -> Result { - Ok(self) - } - #[inline] fn decode_entry(&mut self) -> Result>, C::Error> { let Some(value) = self.iter.next() else { @@ -476,19 +508,21 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> MapDecoder<'de> } #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) + fn decode_remaining_entries( + &mut self, + ) -> Result, ::Error> { + Ok(IterValuePairsDecoder::new(self.cx, self.iter.as_slice())) } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> MapEntriesDecoder<'de> - for IterValuePairsDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> MapEntriesDecoder<'de> + for IterValuePairsDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeMapEntryKey<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeMapEntryKey<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; - type DecodeMapEntryValue<'this> = ValueDecoder<'a, 'de, F, C> where Self: 'this; + type DecodeMapEntryValue<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; #[inline] fn decode_map_entry_key(&mut self) -> Result>, C::Error> { @@ -514,19 +548,19 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> MapEntriesDecoder<'de> } #[inline] - fn end(self) -> Result<(), C::Error> { + fn end_map_entries(self) -> Result<(), C::Error> { Ok(()) } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> MapEntryDecoder<'de> - for IterValuePairDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> MapEntryDecoder<'de> + for IterValuePairDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeMapKey<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeMapKey<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; - type DecodeMapValue = ValueDecoder<'a, 'de, F, C>; + type DecodeMapValue = ValueDecoder<'a, 'de, OPT, C>; #[inline] fn decode_map_key(&mut self) -> Result, C::Error> { @@ -544,50 +578,33 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> MapEntryDecoder<'de> } } -#[musli::struct_decoder] -impl<'a, 'de, C: ?Sized + Context, const F: Options> StructDecoder<'de> - for IterValuePairsDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> StructDecoder<'de> + for IterValuePairsDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeField<'this> = IterValuePairDecoder<'a, 'de, F, C> + type DecodeField<'this> = IterValuePairDecoder<'a, 'de, OPT, C> where Self: 'this; - type IntoStructFields = Self; - - #[inline] - fn cx(&self) -> &Self::Cx { - self.cx - } #[inline] fn size_hint(&self) -> SizeHint { MapDecoder::size_hint(self) } - #[inline] - fn into_struct_fields(self) -> Result { - Ok(self) - } - #[inline] fn decode_field(&mut self) -> Result>, C::Error> { MapDecoder::decode_entry(self) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - MapDecoder::end(self) - } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> StructFieldsDecoder<'de> - for IterValuePairsDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> StructFieldsDecoder<'de> + for IterValuePairsDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeStructFieldName<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeStructFieldName<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; - type DecodeStructFieldValue<'this> = ValueDecoder<'a, 'de, F, C> where Self: 'this; + type DecodeStructFieldValue<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; #[inline] fn decode_struct_field_name(&mut self) -> Result, C::Error> { @@ -613,20 +630,20 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> StructFieldsDecoder<'de> } #[inline] - fn end(self) -> Result<(), C::Error> { + fn end_struct_fields(self) -> Result<(), C::Error> { Ok(()) } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> StructFieldDecoder<'de> - for IterValuePairDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> StructFieldDecoder<'de> + for IterValuePairDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeFieldName<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeFieldName<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; - type DecodeFieldValue = ValueDecoder<'a, 'de, F, C>; + type DecodeFieldValue = ValueDecoder<'a, 'de, OPT, C>; #[inline] fn decode_field_name(&mut self) -> Result, C::Error> { @@ -645,12 +662,12 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> StructFieldDecoder<'de> } /// A decoder over a simple value pair iterator. -pub struct IterValuePairDecoder<'a, 'de, const F: Options, C: ?Sized> { +pub struct IterValuePairDecoder<'a, 'de, const OPT: Options, C: ?Sized> { cx: &'a C, pair: &'de (Value, Value), } -impl<'a, 'de, const F: Options, C: ?Sized> IterValuePairDecoder<'a, 'de, F, C> { +impl<'a, 'de, const OPT: Options, C: ?Sized> IterValuePairDecoder<'a, 'de, OPT, C> { #[inline] const fn new(cx: &'a C, pair: &'de (Value, Value)) -> Self { Self { cx, pair } @@ -658,27 +675,27 @@ impl<'a, 'de, const F: Options, C: ?Sized> IterValuePairDecoder<'a, 'de, F, C> { } /// A decoder over a simple value pair as a variant. -pub struct IterValueVariantDecoder<'a, 'de, const F: Options, C: ?Sized> { +pub struct IterValueVariantDecoder<'a, 'de, const OPT: Options, C: ?Sized> { cx: &'a C, pair: &'de (Value, Value), } #[cfg(feature = "alloc")] -impl<'a, 'de, const F: Options, C: ?Sized> IterValueVariantDecoder<'a, 'de, F, C> { +impl<'a, 'de, const OPT: Options, C: ?Sized> IterValueVariantDecoder<'a, 'de, OPT, C> { #[inline] const fn new(cx: &'a C, pair: &'de (Value, Value)) -> Self { Self { cx, pair } } } -impl<'a, 'de, C: ?Sized + Context, const F: Options> VariantDecoder<'de> - for IterValueVariantDecoder<'a, 'de, F, C> +impl<'a, 'de, C: ?Sized + Context, const OPT: Options> VariantDecoder<'de> + for IterValueVariantDecoder<'a, 'de, OPT, C> { type Cx = C; - type DecodeTag<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeTag<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; - type DecodeValue<'this> = ValueDecoder<'a, 'de, F, C> + type DecodeValue<'this> = ValueDecoder<'a, 'de, OPT, C> where Self: 'this; @@ -696,11 +713,6 @@ impl<'a, 'de, C: ?Sized + Context, const F: Options> VariantDecoder<'de> fn skip_value(&mut self) -> Result { Ok(true) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) - } } /// Conversion trait for numbers. diff --git a/crates/musli-value/src/en.rs b/crates/musli-value/src/en.rs index b9d2d9580..dc8984f93 100644 --- a/crates/musli-value/src/en.rs +++ b/crates/musli-value/src/en.rs @@ -8,8 +8,8 @@ use alloc::vec::Vec; use musli::en::{Encode, Encoder}; #[cfg(feature = "alloc")] use musli::en::{ - MapEncoder, MapEntriesEncoder, MapEntryEncoder, SequenceEncoder, StructEncoder, - StructFieldEncoder, VariantEncoder, + MapEncoder, MapEntriesEncoder, MapEntryEncoder, PackEncoder, SequenceEncoder, StructEncoder, + StructFieldEncoder, TupleEncoder, VariantEncoder, }; use musli::Context; @@ -339,7 +339,7 @@ where let mut variant = self.encode_variant()?; variant.encode_tag()?.encode(tag)?; variant.encode_value()?.encode_unit()?; - variant.end()?; + variant.end_variant()?; Ok(()) } @@ -413,22 +413,70 @@ where type Cx = C; type Ok = (); - type EncodeNext<'this> = ValueEncoder<'a, &'this mut Vec, C> + type EncodeElement<'this> = ValueEncoder<'a, &'this mut Vec, C> where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_element(&mut self) -> Result, C::Error> { Ok(ValueEncoder::new(self.cx, &mut self.values)) } #[inline] - fn end(self) -> Result { + fn end_sequence(self) -> Result { self.output.write(Value::Sequence(self.values)); Ok(()) } } +#[cfg(feature = "alloc")] +impl<'a, O, C> PackEncoder for SequenceValueEncoder<'a, O, C> +where + O: ValueOutput, + C: ?Sized + Context, +{ + type Cx = C; + type Ok = (); + + type EncodePacked<'this> = ValueEncoder<'a, &'this mut Vec, C> + where + Self: 'this; + + #[inline] + fn encode_packed(&mut self) -> Result, C::Error> { + SequenceEncoder::encode_element(self) + } + + #[inline] + fn end_pack(self) -> Result { + SequenceEncoder::end_sequence(self) + } +} + +#[cfg(feature = "alloc")] +impl<'a, O, C> TupleEncoder for SequenceValueEncoder<'a, O, C> +where + O: ValueOutput, + C: ?Sized + Context, +{ + type Cx = C; + type Ok = (); + + type EncodeTupleField<'this> = ValueEncoder<'a, &'this mut Vec, C> + where + Self: 'this; + + #[inline] + fn encode_tuple_field(&mut self) -> Result, C::Error> { + SequenceEncoder::encode_element(self) + } + + #[inline] + fn end_tuple(self) -> Result { + SequenceEncoder::end_sequence(self) + } +} + /// A pairs encoder. #[cfg(feature = "alloc")] pub struct MapValueEncoder<'a, O, C: ?Sized> { @@ -457,17 +505,17 @@ where { type Cx = C; type Ok = (); - type EncodeEntry<'this> = PairValueEncoder<'this, C> + type EncodeMapEntry<'this> = PairValueEncoder<'this, C> where Self: 'this; #[inline] - fn encode_entry(&mut self) -> Result, C::Error> { + fn encode_map_entry(&mut self) -> Result, C::Error> { Ok(PairValueEncoder::new(self.cx, &mut self.values)) } #[inline] - fn end(self) -> Result { + fn end_map(self) -> Result { self.output.write(Value::Map(self.values)); Ok(()) } @@ -509,7 +557,7 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entries(self) -> Result { self.output.write(Value::Map(self.values)); Ok(()) } @@ -524,17 +572,17 @@ where type Cx = C; type Ok = (); - type EncodeField<'this> = PairValueEncoder<'this, C> + type EncodeStructField<'this> = PairValueEncoder<'this, C> where Self: 'this; #[inline] - fn encode_field(&mut self) -> Result, C::Error> { + fn encode_struct_field(&mut self) -> Result, C::Error> { Ok(PairValueEncoder::new(self.cx, &mut self.values)) } #[inline] - fn end(self) -> Result { + fn end_struct(self) -> Result { self.output.write(Value::Map(self.values)); Ok(()) } @@ -583,7 +631,7 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entry(self) -> Result { self.output.push(self.pair); Ok(()) } @@ -612,7 +660,7 @@ where } #[inline] - fn end(self) -> Result { + fn end_field(self) -> Result { self.output.push(self.pair); Ok(()) } @@ -664,7 +712,7 @@ where } #[inline] - fn end(self) -> Result { + fn end_variant(self) -> Result { self.output.write(Value::Variant(Box::new(self.pair))); Ok(()) } @@ -701,17 +749,17 @@ where type Cx = C; type Ok = (); - type EncodeNext<'this> = ValueEncoder<'a, &'this mut Vec, C> + type EncodeElement<'this> = ValueEncoder<'a, &'this mut Vec, C> where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_element(&mut self) -> Result, C::Error> { Ok(ValueEncoder::new(self.cx, &mut self.values)) } #[inline] - fn end(self) -> Result { + fn end_sequence(self) -> Result { self.output.write(Value::Variant(Box::new(( self.variant, Value::Sequence(self.values), @@ -720,6 +768,30 @@ where } } +#[cfg(feature = "alloc")] +impl<'a, O, C> TupleEncoder for VariantSequenceEncoder<'a, O, C> +where + O: ValueOutput, + C: ?Sized + Context, +{ + type Cx = C; + type Ok = (); + + type EncodeTupleField<'this> = ValueEncoder<'a, &'this mut Vec, C> + where + Self: 'this; + + #[inline] + fn encode_tuple_field(&mut self) -> Result, C::Error> { + SequenceEncoder::encode_element(self) + } + + #[inline] + fn end_tuple(self) -> Result { + SequenceEncoder::end_sequence(self) + } +} + /// A variant struct encoder. #[cfg(feature = "alloc")] pub struct VariantStructEncoder<'a, O, C: ?Sized> { @@ -751,17 +823,17 @@ where type Cx = C; type Ok = (); - type EncodeField<'this> = PairValueEncoder<'this, C> + type EncodeStructField<'this> = PairValueEncoder<'this, C> where Self: 'this; #[inline] - fn encode_field(&mut self) -> Result, C::Error> { + fn encode_struct_field(&mut self) -> Result, C::Error> { Ok(PairValueEncoder::new(self.cx, &mut self.fields)) } #[inline] - fn end(self) -> Result { + fn end_struct(self) -> Result { self.output.write(Value::Variant(Box::new(( self.variant, Value::Map(self.fields), diff --git a/crates/musli-value/src/value.rs b/crates/musli-value/src/value.rs index 5bfc23545..a03c976d6 100644 --- a/crates/musli-value/src/value.rs +++ b/crates/musli-value/src/value.rs @@ -82,19 +82,19 @@ impl Value { /// Construct a [AsValueDecoder] implementation out of this value which /// emits the specified error `E`. #[inline] - pub fn into_value_decoder( + pub fn into_value_decoder( self, cx: &C, - ) -> AsValueDecoder<'_, F, C> { + ) -> AsValueDecoder<'_, OPT, C> { AsValueDecoder::new(cx, self) } /// Get a decoder associated with a value. #[inline] - pub(crate) fn decoder<'a, 'de, const F: Options, C: ?Sized>( + pub(crate) fn decoder<'a, 'de, const OPT: Options, C: ?Sized>( &'de self, cx: &'a C, - ) -> ValueDecoder<'a, 'de, F, C> { + ) -> ValueDecoder<'a, 'de, OPT, C> { ValueDecoder::new(cx, self) } } @@ -319,7 +319,7 @@ impl<'de, C: ?Sized + Context> Visitor<'de, C> for AnyVisitor { #[cfg(feature = "alloc")] #[inline] - fn visit_sequence(self, _: &C, mut seq: D) -> Result + fn visit_sequence(self, _: &C, seq: &mut D) -> Result where D: SequenceDecoder<'de, Cx = C>, { @@ -329,13 +329,12 @@ impl<'de, C: ?Sized + Context> Visitor<'de, C> for AnyVisitor { out.push(item); } - seq.end()?; Ok(Value::Sequence(out)) } #[cfg(feature = "alloc")] #[inline] - fn visit_map(self, _: &C, mut map: D) -> Result + fn visit_map(self, _: &C, map: &mut D) -> Result where D: MapDecoder<'de, Cx = C>, { @@ -347,7 +346,6 @@ impl<'de, C: ?Sized + Context> Visitor<'de, C> for AnyVisitor { out.push((first, second)); } - map.end()?; Ok(Value::Map(out)) } @@ -371,13 +369,12 @@ impl<'de, C: ?Sized + Context> Visitor<'de, C> for AnyVisitor { #[cfg(feature = "alloc")] #[inline] - fn visit_variant(self, _: &C, mut variant: D) -> Result + fn visit_variant(self, _: &C, variant: &mut D) -> Result where D: VariantDecoder<'de, Cx = C>, { let first = variant.decode_tag()?.decode()?; let second = variant.decode_value()?.decode()?; - variant.end()?; Ok(Value::Variant(Box::new((first, second)))) } } @@ -537,7 +534,7 @@ impl Encode for Value { #[cfg(feature = "alloc")] Value::Sequence(values) => encoder.encode_sequence_fn(values.len(), |sequence| { for value in values { - sequence.encode_next()?.encode(value)?; + sequence.encode_element()?.encode(value)?; } Ok(()) @@ -566,12 +563,12 @@ impl Encode for Value { } /// Value's [AsDecoder] implementation. -pub struct AsValueDecoder<'a, const F: Options, C: ?Sized> { +pub struct AsValueDecoder<'a, const OPT: Options, C: ?Sized> { cx: &'a C, value: Value, } -impl<'a, const F: Options, C: ?Sized> AsValueDecoder<'a, F, C> { +impl<'a, const OPT: Options, C: ?Sized> AsValueDecoder<'a, OPT, C> { /// Construct a new buffered value decoder. #[inline] pub fn new(cx: &'a C, value: Value) -> Self { @@ -579,9 +576,9 @@ impl<'a, const F: Options, C: ?Sized> AsValueDecoder<'a, F, C> { } } -impl<'a, const F: Options, C: ?Sized + Context> AsDecoder for AsValueDecoder<'a, F, C> { +impl<'a, const OPT: Options, C: ?Sized + Context> AsDecoder for AsValueDecoder<'a, OPT, C> { type Cx = C; - type Decoder<'this> = ValueDecoder<'a, 'this, F, C> where Self: 'this; + type Decoder<'this> = ValueDecoder<'a, 'this, OPT, C> where Self: 'this; #[inline] fn as_decoder(&self) -> Result, C::Error> { diff --git a/crates/musli-wire/src/de.rs b/crates/musli-wire/src/de.rs index 2db365794..9a31d264b 100644 --- a/crates/musli-wire/src/de.rs +++ b/crates/musli-wire/src/de.rs @@ -1,11 +1,13 @@ use core::fmt; +use core::mem::take; #[cfg(feature = "alloc")] use alloc::vec::Vec; use musli::de::{ Decode, Decoder, MapDecoder, MapEntriesDecoder, MapEntryDecoder, PackDecoder, SequenceDecoder, - SizeHint, StructDecoder, StructFieldDecoder, StructFieldsDecoder, ValueVisitor, VariantDecoder, + SizeHint, StructDecoder, StructFieldDecoder, StructFieldsDecoder, TupleDecoder, ValueVisitor, + VariantDecoder, }; use musli::Context; use musli_common::int::continuation as c; @@ -17,12 +19,16 @@ use crate::tag::Kind; use crate::tag::Tag; /// A very simple decoder. -pub struct WireDecoder<'a, R, const F: Options, C: ?Sized> { +pub struct WireDecoder<'a, R, const OPT: Options, C: ?Sized> { cx: &'a C, reader: R, } -impl<'a, R, const F: Options, C: ?Sized> WireDecoder<'a, R, F, C> { +impl<'a, 'de, R, const OPT: Options, C> WireDecoder<'a, R, OPT, C> +where + R: Reader<'de>, + C: ?Sized + Context, +{ /// Construct a new fixed width message encoder. #[inline] pub(crate) fn new(cx: &'a C, reader: R) -> Self { @@ -30,43 +36,68 @@ impl<'a, R, const F: Options, C: ?Sized> WireDecoder<'a, R, F, C> { } } -impl<'a, 'de, R, const F: Options, C> WireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> WireDecoder<'a, Limit, OPT, C> +where + C: ?Sized + Context, + R: Reader<'de>, +{ + #[inline] + fn end(mut self) -> Result<(), C::Error> { + if self.reader.remaining() > 0 { + self.reader.skip(self.cx, self.reader.remaining())?; + } + + Ok(()) + } +} + +impl<'a, 'de, R, const OPT: Options, C> WireDecoder<'a, R, OPT, C> where R: Reader<'de>, C: ?Sized + Context, { /// Skip over any sequences of values. - pub(crate) fn skip_any(&mut self) -> Result<(), C::Error> { - let tag = Tag::from_byte(self.reader.read_byte(self.cx)?); + pub(crate) fn skip_any(mut self) -> Result<(), C::Error> { + let mut remaining = 1; - match tag.kind() { - Kind::Pack => { - let len = 2usize.pow(tag.data_raw() as u32); - self.reader.skip(self.cx, len)?; - } - Kind::Prefix => { - let len = if let Some(len) = tag.data() { - len as usize - } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? - }; + while remaining > 0 { + remaining -= 1; - self.reader.skip(self.cx, len)?; - } - Kind::Sequence => { - let len = if let Some(len) = tag.data() { - len as usize - } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? - }; + let tag = Tag::from_byte(self.reader.read_byte(self.cx)?); - for _ in 0..len { - self.skip_any()?; + match tag.kind() { + Kind::Pack => { + let len = 2usize.pow(tag.data_raw() as u32); + self.reader.skip(self.cx, len)?; } - } - Kind::Continuation => { - if tag.data().is_none() { - let _ = c::decode::<_, _, u128>(self.cx, self.reader.borrow_mut())?; + Kind::Prefix => { + let len = if let Some(len) = tag.data() { + len as usize + } else { + musli_common::int::decode_usize::<_, _, OPT>( + self.cx, + self.reader.borrow_mut(), + )? + }; + + self.reader.skip(self.cx, len)?; + } + Kind::Sequence => { + let len = if let Some(len) = tag.data() { + len as usize + } else { + musli_common::int::decode_usize::<_, _, OPT>( + self.cx, + self.reader.borrow_mut(), + )? + }; + + remaining += len; + } + Kind::Continuation => { + if tag.data().is_none() { + let _ = c::decode::<_, _, u128>(self.cx, self.reader.borrow_mut())?; + } } } } @@ -82,7 +113,7 @@ where Kind::Sequence => Ok(if let Some(len) = tag.data() { len as usize } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? + musli_common::int::decode_usize::<_, _, OPT>(self.cx, self.reader.borrow_mut())? }), _ => Err(self.cx.message(Expected { expected: Kind::Sequence, @@ -95,16 +126,16 @@ where #[inline] fn shared_decode_pair_sequence( mut self, - ) -> Result, C::Error> { + ) -> Result, C::Error> { let len = self.decode_sequence_len()?; - Ok(RemainingWireDecoder::new(len / 2, self)) + Ok(RemainingWireDecoder::new(self.cx, self.reader, len / 2)) } // Standard function for decoding a pair sequence. #[inline] - fn shared_decode_sequence(mut self) -> Result, C::Error> { + fn shared_decode_sequence(mut self) -> Result, C::Error> { let len = self.decode_sequence_len()?; - Ok(RemainingWireDecoder::new(len, self)) + Ok(RemainingWireDecoder::new(self.cx, self.reader, len)) } /// Decode the length of a prefix. @@ -116,7 +147,7 @@ where Kind::Prefix => Ok(if let Some(len) = tag.data() { len as usize } else { - musli_common::int::decode_usize::<_, _, F>(self.cx, self.reader.borrow_mut())? + musli_common::int::decode_usize::<_, _, OPT>(self.cx, self.reader.borrow_mut())? }), Kind::Pack => { let Some(len) = 2usize.checked_pow(tag.data_raw() as u32) else { @@ -135,13 +166,56 @@ where /// This simplifies implementing decoders that do not have any special handling /// for length-prefixed types. #[doc(hidden)] -pub struct RemainingWireDecoder<'a, R, const F: Options, C: ?Sized> { +pub struct RemainingWireDecoder<'a, R, const OPT: Options, C: ?Sized> { + cx: &'a C, + reader: R, remaining: usize, - decoder: WireDecoder<'a, R, F, C>, +} + +impl<'a, 'de, R, const OPT: Options, C> RemainingWireDecoder<'a, R, OPT, C> +where + C: ?Sized + Context, + R: Reader<'de>, +{ + #[inline] + fn new(cx: &'a C, reader: R, remaining: usize) -> Self { + Self { + cx, + reader, + remaining, + } + } + + #[inline] + fn skip_sequence_remaining(mut self) -> Result<(), C::Error> { + loop { + let Some(value) = SequenceDecoder::decode_next(&mut self)? else { + break; + }; + + value.skip()?; + } + + Ok(()) + } + + #[inline] + fn skip_remaining_entries(mut self) -> Result<(), C::Error> { + loop { + let Some(value) = self.decode_map_entry_key()? else { + break; + }; + + value.skip()?; + self.skip_map_entry_value()?; + } + + Ok(()) + } } #[musli::decoder] -impl<'a, 'de, R, const F: Options, C> Decoder<'de> for WireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> Decoder<'de> for WireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, @@ -149,13 +223,15 @@ where type Cx = C; type Error = C::Error; type Mode = C::Mode; - type WithContext<'this, U> = WireDecoder<'this, R, F, U> where U: 'this + Context; - type DecodePack = WireDecoder<'a, Limit, F, C>; + type WithContext<'this, U> = WireDecoder<'this, R, OPT, U> where U: 'this + Context; + type DecodePack = WireDecoder<'a, Limit, OPT, C>; type DecodeSome = Self; - type DecodeSequence = RemainingWireDecoder<'a, R, F, C>; - type DecodeTuple = TupleWireDecoder<'a, R, F, C>; - type DecodeMap = RemainingWireDecoder<'a, R, F, C>; - type DecodeStruct = RemainingWireDecoder<'a, R, F, C>; + type DecodeSequence = RemainingWireDecoder<'a, R, OPT, C>; + type DecodeTuple = RemainingWireDecoder<'a, R, OPT, C>; + type DecodeMap = RemainingWireDecoder<'a, R, OPT, C>; + type DecodeMapEntries = RemainingWireDecoder<'a, R, OPT, C>; + type DecodeStruct = RemainingWireDecoder<'a, R, OPT, C>; + type DecodeStructFields = RemainingWireDecoder<'a, R, OPT, C>; type DecodeVariant = Self; #[inline] @@ -185,21 +261,26 @@ where } #[inline] - fn skip(mut self) -> Result<(), C::Error> { + fn skip(self) -> Result<(), C::Error> { self.skip_any() } #[inline] - fn decode_unit(mut self) -> Result<(), C::Error> { - self.skip_any()?; - Ok(()) + fn decode_unit(self) -> Result<(), C::Error> { + self.skip() } #[inline] - fn decode_pack(mut self) -> Result { + fn decode_pack(mut self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodePack) -> Result, + { let mark = self.cx.mark(); let len = self.decode_len(mark)?; - Ok(WireDecoder::new(self.cx, self.reader.limit(len))) + let mut decoder = WireDecoder::new(self.cx, self.reader.limit(len)); + let output = f(&mut decoder)?; + decoder.end()?; + Ok(output) } #[inline] @@ -299,27 +380,27 @@ where #[inline] fn decode_u8(self) -> Result { - crate::wire_int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_u16(self) -> Result { - crate::wire_int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_u32(self) -> Result { - crate::wire_int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_u64(self) -> Result { - crate::wire_int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_u128(self) -> Result { - crate::wire_int::decode_unsigned::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_unsigned::<_, _, _, OPT>(self.cx, self.reader) } #[inline] @@ -329,27 +410,27 @@ where #[inline] fn decode_i16(self) -> Result { - crate::wire_int::decode_signed::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_i32(self) -> Result { - crate::wire_int::decode_signed::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_i64(self) -> Result { - crate::wire_int::decode_signed::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_i128(self) -> Result { - crate::wire_int::decode_signed::<_, _, _, F>(self.cx, self.reader) + crate::wire_int::decode_signed::<_, _, _, OPT>(self.cx, self.reader) } #[inline] fn decode_usize(self) -> Result { - crate::wire_int::decode_length::<_, _, F>(self.cx, self.reader) + crate::wire_int::decode_length::<_, _, OPT>(self.cx, self.reader) } #[inline] @@ -389,35 +470,72 @@ where } #[inline] - fn decode_sequence(self) -> Result { - self.shared_decode_sequence() + fn decode_sequence(self, f: F) -> Result::Error> + where + F: FnOnce(&mut Self::DecodeSequence) -> Result::Error>, + { + let mut decoder = self.shared_decode_sequence()?; + let output = f(&mut decoder)?; + decoder.skip_sequence_remaining()?; + Ok(output) } #[inline] - fn decode_tuple(mut self, len: usize) -> Result { - let actual = self.decode_sequence_len()?; + fn decode_tuple(self, len: usize, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeTuple) -> Result, + { + let mut decoder = self.shared_decode_sequence()?; - if len != actual { - return Err(self.cx.message(format_args!( - "tuple length mismatch: len: {len}, actual: {actual}" + if len != decoder.remaining { + return Err(decoder.cx.message(format_args!( + "Tuple length mismatch: len: {len}, actual: {}", + decoder.remaining ))); } - Ok(TupleWireDecoder::new(self.cx, self.reader, len)) + let output = f(&mut decoder)?; + decoder.skip_sequence_remaining()?; + Ok(output) + } + + #[inline] + fn decode_map(self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeMap) -> Result, + { + let mut decoder = self.shared_decode_pair_sequence()?; + let output = f(&mut decoder)?; + decoder.skip_remaining_entries()?; + Ok(output) } #[inline] - fn decode_map(self) -> Result { + fn decode_map_entries(self) -> Result { self.shared_decode_pair_sequence() } #[inline] - fn decode_struct(self, _: Option) -> Result { + fn decode_struct(self, _: Option, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeStruct) -> Result, + { + let mut decoder = self.shared_decode_pair_sequence()?; + let output = f(&mut decoder)?; + decoder.skip_remaining_entries()?; + Ok(output) + } + + #[inline] + fn decode_struct_fields(self, _: Option) -> Result { self.shared_decode_pair_sequence() } #[inline] - fn decode_variant(mut self) -> Result { + fn decode_variant(mut self, f: F) -> Result + where + F: FnOnce(&mut Self::DecodeVariant) -> Result, + { let tag = Tag::from_byte(self.reader.read_byte(self.cx)?); if tag != Tag::new(Kind::Sequence, 2) { @@ -427,47 +545,31 @@ where })); } - Ok(self) + f(&mut self) } } -impl<'a, 'de, R, const F: Options, C> PackDecoder<'de> for WireDecoder<'a, Limit, F, C> +impl<'a, 'de, R, const OPT: Options, C> PackDecoder<'de> for WireDecoder<'a, Limit, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeNext<'this> = StorageDecoder<'a, as Reader<'de>>::Mut<'this>, F, C> where Self: 'this; + type DecodeNext<'this> = StorageDecoder<'a, as Reader<'de>>::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_next(&mut self) -> Result, C::Error> { Ok(StorageDecoder::new(self.cx, self.reader.borrow_mut())) } - - #[inline] - fn end(mut self) -> Result<(), C::Error> { - if self.reader.remaining() > 0 { - self.reader.skip(self.cx, self.reader.remaining())?; - } - - Ok(()) - } -} - -impl<'a, R, const F: Options, C: ?Sized> RemainingWireDecoder<'a, R, F, C> { - #[inline] - fn new(remaining: usize, decoder: WireDecoder<'a, R, F, C>) -> Self { - Self { remaining, decoder } - } } -impl<'a, 'de, R, const F: Options, C> SequenceDecoder<'de> for RemainingWireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> SequenceDecoder<'de> for RemainingWireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeNext<'this> = WireDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeNext<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { @@ -481,21 +583,53 @@ where } self.remaining -= 1; - Ok(Some(WireDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(WireDecoder::new(self.cx, self.reader.borrow_mut()))) + } +} + +impl<'a, 'de, R, const OPT: Options, C> PackDecoder<'de> for RemainingWireDecoder<'a, R, OPT, C> +where + C: ?Sized + Context, + R: Reader<'de>, +{ + type Cx = C; + type DecodeNext<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; + + #[inline] + fn decode_next(&mut self) -> Result, C::Error> { + if self.remaining == 0 { + return Err(self + .cx + .message(format_args!("No more tuple elements to decode"))); + } + + self.remaining -= 1; + Ok(WireDecoder::new(self.cx, self.reader.borrow_mut())) + } +} + +impl<'a, 'de, R, const OPT: Options, C> TupleDecoder<'de> for RemainingWireDecoder<'a, R, OPT, C> +where + C: ?Sized + Context, + R: Reader<'de>, +{ + type Cx = C; + type DecodeNext<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; + + #[inline] + fn decode_next(&mut self) -> Result, C::Error> { + PackDecoder::decode_next(self) } } -impl<'a, 'de, R, const F: Options, C> VariantDecoder<'de> for WireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> VariantDecoder<'de> for WireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeTag<'this> = WireDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; - type DecodeValue<'this> = WireDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeTag<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; + type DecodeValue<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_tag(&mut self) -> Result, C::Error> { @@ -509,43 +643,27 @@ where #[inline] fn skip_value(&mut self) -> Result { - self.skip_any()?; + self.decode_value()?.skip()?; Ok(true) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - Ok(()) - } } -#[musli::map_decoder] -impl<'a, 'de, R, const F: Options, C> MapDecoder<'de> for RemainingWireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> MapDecoder<'de> for RemainingWireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeEntry<'this> = WireDecoder<'a, R::Mut<'this>, F, C> + type DecodeEntry<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type IntoMapEntries = Self; - - #[inline] - fn cx(&self) -> &C { - self.decoder.cx - } + type DecodeRemainingEntries<'this> = RemainingWireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { SizeHint::Exact(self.remaining) } - #[inline] - fn into_map_entries(self) -> Result { - Ok(self) - } - #[inline] fn decode_entry(&mut self) -> Result>, C::Error> { if self.remaining == 0 { @@ -553,20 +671,26 @@ where } self.remaining -= 1; - Ok(Some(WireDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(WireDecoder::new(self.cx, self.reader.borrow_mut()))) + } + + #[inline] + fn decode_remaining_entries(&mut self) -> Result, C::Error> { + Ok(RemainingWireDecoder::new( + self.cx, + self.reader.borrow_mut(), + take(&mut self.remaining), + )) } } -impl<'a, 'de, R, const F: Options, C> MapEntryDecoder<'de> for WireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> MapEntryDecoder<'de> for WireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeMapKey<'this> = WireDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeMapKey<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; type DecodeMapValue = Self; #[inline] @@ -580,57 +704,40 @@ where } #[inline] - fn skip_map_value(mut self) -> Result { - self.skip_any()?; + fn skip_map_value(self) -> Result { + self.decode_map_value()?.skip()?; Ok(true) } } -#[musli::struct_decoder] -impl<'a, 'de, R, const F: Options, C> StructDecoder<'de> for RemainingWireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> StructDecoder<'de> for RemainingWireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeField<'this> = WireDecoder<'a, R::Mut<'this>, F, C> + type DecodeField<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type IntoStructFields = Self; - - #[inline] - fn cx(&self) -> &C { - self.decoder.cx - } #[inline] fn size_hint(&self) -> SizeHint { MapDecoder::size_hint(self) } - #[inline] - fn into_struct_fields(self) -> Result { - Ok(self) - } - #[inline] fn decode_field(&mut self) -> Result>, C::Error> { MapDecoder::decode_entry(self) } - - #[inline] - fn end(self) -> Result<(), C::Error> { - MapDecoder::end(self) - } } -impl<'a, 'de, R, const F: Options, C> StructFieldDecoder<'de> for WireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> StructFieldDecoder<'de> for WireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeFieldName<'this> = WireDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; + type DecodeFieldName<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; type DecodeFieldValue = Self; #[inline] @@ -649,16 +756,17 @@ where } } -impl<'a, 'de, R, const F: Options, C> MapEntriesDecoder<'de> for RemainingWireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> MapEntriesDecoder<'de> + for RemainingWireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeMapEntryKey<'this> = WireDecoder<'a, R::Mut<'this>, F, C> + type DecodeMapEntryKey<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type DecodeMapEntryValue<'this> = WireDecoder<'a, R::Mut<'this>, F, C> + type DecodeMapEntryValue<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; @@ -669,79 +777,65 @@ where } self.remaining -= 1; - Ok(Some(WireDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - ))) + Ok(Some(WireDecoder::new(self.cx, self.reader.borrow_mut()))) } #[inline] fn decode_map_entry_value(&mut self) -> Result, C::Error> { - Ok(WireDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + Ok(WireDecoder::new(self.cx, self.reader.borrow_mut())) } #[inline] fn skip_map_entry_value(&mut self) -> Result { - self.decode_map_entry_value()?.skip_any()?; + self.decode_map_entry_value()?.skip()?; Ok(true) } + + #[inline] + fn end_map_entries(self) -> Result<(), C::Error> { + self.skip_remaining_entries()?; + Ok(()) + } } -impl<'a, 'de, R, const F: Options, C> StructFieldsDecoder<'de> for RemainingWireDecoder<'a, R, F, C> +impl<'a, 'de, R, const OPT: Options, C> StructFieldsDecoder<'de> + for RemainingWireDecoder<'a, R, OPT, C> where C: ?Sized + Context, R: Reader<'de>, { type Cx = C; - type DecodeStructFieldName<'this> = WireDecoder<'a, R::Mut<'this>, F, C> + type DecodeStructFieldName<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; - type DecodeStructFieldValue<'this> = WireDecoder<'a, R::Mut<'this>, F, C> + type DecodeStructFieldValue<'this> = WireDecoder<'a, R::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn decode_struct_field_name(&mut self) -> Result, C::Error> { - if self.remaining == 0 { - return Err(self - .decoder - .cx - .message("Ran out of struct fields to decode")); - } + let cx = self.cx; - self.remaining -= 1; - Ok(WireDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + let Some(decoder) = Self::decode_map_entry_key(self)? else { + return Err(cx.message("Ran out of fields to decode")); + }; + + Ok(decoder) } #[inline] fn decode_struct_field_value(&mut self) -> Result, C::Error> { - Ok(WireDecoder::new( - self.decoder.cx, - self.decoder.reader.borrow_mut(), - )) + Self::decode_map_entry_value(self) } #[inline] fn skip_struct_field_value(&mut self) -> Result { - self.decode_struct_field_value()?.skip_any()?; - Ok(true) + Self::skip_map_entry_value(self) } #[inline] - fn end(mut self) -> Result<(), C::Error> { - while self.remaining > 0 { - self.remaining -= 1; - self.decode_struct_field_name()?.skip_any()?; - self.decode_struct_field_value()?.skip_any()?; - } - - Ok(()) + fn end_struct_fields(self) -> Result<(), C::Error> { + Self::end_map_entries(self) } } @@ -801,53 +895,3 @@ impl fmt::Display for BadLength { write!(f, "Bad length, got {actual} but expect {expected}") } } - -/// A tuple wire decoder. -pub struct TupleWireDecoder<'a, R, const F: Options, C: ?Sized> { - cx: &'a C, - reader: R, - remaining: usize, -} - -impl<'a, R, const F: Options, C: ?Sized> TupleWireDecoder<'a, R, F, C> { - /// Construct a new fixed width message encoder. - #[inline] - pub(crate) fn new(cx: &'a C, reader: R, remaining: usize) -> Self { - Self { - cx, - reader, - remaining, - } - } -} - -impl<'a, 'de, R, const F: Options, C> PackDecoder<'de> for TupleWireDecoder<'a, R, F, C> -where - C: ?Sized + Context, - R: Reader<'de>, -{ - type Cx = C; - type DecodeNext<'this> = WireDecoder<'a, R::Mut<'this>, F, C> where Self: 'this; - - #[inline] - fn decode_next(&mut self) -> Result, C::Error> { - if self.remaining == 0 { - return Err(self - .cx - .message(format_args!("No more tuple elements to decode"))); - } - - self.remaining -= 1; - Ok(WireDecoder::new(self.cx, self.reader.borrow_mut())) - } - - #[inline] - fn end(mut self) -> Result<(), C::Error> { - while self.remaining > 0 { - WireDecoder::<_, F, _>::new(self.cx, self.reader.borrow_mut()).skip_any()?; - self.remaining -= 1; - } - - Ok(()) - } -} diff --git a/crates/musli-wire/src/en.rs b/crates/musli-wire/src/en.rs index 2491b82ea..dce276ebb 100644 --- a/crates/musli-wire/src/en.rs +++ b/crates/musli-wire/src/en.rs @@ -1,8 +1,8 @@ use core::fmt; use musli::en::{ - Encode, Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, SequenceEncoder, - StructEncoder, StructFieldEncoder, VariantEncoder, + Encode, Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, PackEncoder, SequenceEncoder, + StructEncoder, StructFieldEncoder, TupleEncoder, VariantEncoder, }; use musli::{Buf, Context}; use musli_storage::en::StorageEncoder; @@ -12,12 +12,12 @@ use crate::tag::{Kind, Tag, MAX_INLINE_LEN}; use crate::writer::{BufWriter, Writer}; /// A very simple encoder. -pub struct WireEncoder<'a, W, const F: Options, C: ?Sized> { +pub struct WireEncoder<'a, W, const OPT: Options, C: ?Sized> { cx: &'a C, writer: W, } -impl<'a, W, const F: Options, C> WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> WireEncoder<'a, W, OPT, C> where W: Writer, C: ?Sized + Context, @@ -38,7 +38,7 @@ where self.writer.write_byte(self.cx, tag.byte())?; if !embedded { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; } Ok(()) @@ -50,20 +50,20 @@ where self.writer.write_byte(self.cx, tag.byte())?; if !embedded { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; } Ok(()) } } -pub struct WirePackEncoder<'a, W, B, const F: Options, C: ?Sized> { +pub struct WirePackEncoder<'a, W, B, const OPT: Options, C: ?Sized> { cx: &'a C, writer: W, buffer: BufWriter, } -impl<'a, W, B, const F: Options, C: ?Sized> WirePackEncoder<'a, W, B, F, C> { +impl<'a, W, B, const OPT: Options, C: ?Sized> WirePackEncoder<'a, W, B, OPT, C> { /// Construct a new fixed width message encoder. #[inline] pub(crate) fn new(cx: &'a C, writer: W, buffer: B) -> Self { @@ -76,7 +76,7 @@ impl<'a, W, B, const F: Options, C: ?Sized> WirePackEncoder<'a, W, B, F, C> { } #[musli::encoder] -impl<'a, W, const F: Options, C> Encoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> Encoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, @@ -85,8 +85,8 @@ where type Error = C::Error; type Ok = (); type Mode = C::Mode; - type WithContext<'this, U> = WireEncoder<'this, W, F, U> where U: 'this + Context; - type EncodePack = WirePackEncoder<'a, W, C::Buf<'a>, F, C>; + type WithContext<'this, U> = WireEncoder<'this, W, OPT, U> where U: 'this + Context; + type EncodePack = WirePackEncoder<'a, W, C::Buf<'a>, OPT, C>; type EncodeSome = Self; type EncodeSequence = Self; type EncodeTuple = Self; @@ -146,7 +146,7 @@ where #[inline] fn encode_bytes(mut self, bytes: &[u8]) -> Result { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), bytes.len())?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), bytes.len())?; self.writer.write_bytes(self.cx, bytes)?; Ok(()) } @@ -157,7 +157,7 @@ where I: IntoIterator, I::Item: AsRef<[u8]>, { - encode_prefix::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + encode_prefix::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; for bytes in vectors { self.writer.write_bytes(self.cx, bytes.as_ref())?; @@ -182,12 +182,16 @@ where #[inline] fn encode_usize(mut self, value: usize) -> Result { - crate::wire_int::encode_length::<_, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_length::<_, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_isize(mut self, value: isize) -> Result { - crate::wire_int::encode_length::<_, _, F>(self.cx, self.writer.borrow_mut(), value as usize) + crate::wire_int::encode_length::<_, _, OPT>( + self.cx, + self.writer.borrow_mut(), + value as usize, + ) } #[inline] @@ -205,27 +209,27 @@ where #[inline] fn encode_u8(mut self, value: u8) -> Result { - crate::wire_int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_u16(mut self, value: u16) -> Result { - crate::wire_int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_u32(mut self, value: u32) -> Result { - crate::wire_int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_u64(mut self, value: u64) -> Result { - crate::wire_int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_u128(mut self, value: u128) -> Result { - crate::wire_int::encode_unsigned::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_unsigned::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] @@ -235,22 +239,22 @@ where #[inline] fn encode_i16(mut self, value: i16) -> Result { - crate::wire_int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_i32(mut self, value: i32) -> Result { - crate::wire_int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_i64(mut self, value: i64) -> Result { - crate::wire_int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] fn encode_i128(mut self, value: i128) -> Result { - crate::wire_int::encode_signed::<_, _, _, F>(self.cx, self.writer.borrow_mut(), value) + crate::wire_int::encode_signed::<_, _, _, OPT>(self.cx, self.writer.borrow_mut(), value) } #[inline] @@ -283,7 +287,7 @@ where self.writer.write_byte(self.cx, tag.byte())?; if !embedded { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; } Ok(self) @@ -316,7 +320,7 @@ where self.writer.write_byte(self.cx, tag.byte())?; if !embedded { - musli_common::int::encode_usize::<_, _, F>(self.cx, self.writer.borrow_mut(), len)?; + musli_common::int::encode_usize::<_, _, OPT>(self.cx, self.writer.borrow_mut(), len)?; } Ok(self) @@ -340,7 +344,7 @@ where { self.writer .write_byte(self.cx, Tag::new(Kind::Sequence, 2).byte())?; - WireEncoder::<_, F, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; + WireEncoder::<_, OPT, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; self.encode_tuple(len) } @@ -355,12 +359,12 @@ where { self.writer .write_byte(self.cx, Tag::new(Kind::Sequence, 2).byte())?; - WireEncoder::<_, F, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; + WireEncoder::<_, OPT, _>::new(self.cx, self.writer.borrow_mut()).encode(tag)?; self.encode_struct(len) } } -impl<'a, W, B, const F: Options, C> SequenceEncoder for WirePackEncoder<'a, W, B, F, C> +impl<'a, W, B, const OPT: Options, C> PackEncoder for WirePackEncoder<'a, W, B, OPT, C> where C: ?Sized + Context, W: Writer, @@ -368,15 +372,15 @@ where { type Cx = C; type Ok = (); - type EncodeNext<'this> = StorageEncoder<'a, &'this mut BufWriter, F, C> where Self: 'this, B: Buf; + type EncodePacked<'this> = StorageEncoder<'a, &'this mut BufWriter, OPT, C> where Self: 'this, B: Buf; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_packed(&mut self) -> Result, C::Error> { Ok(StorageEncoder::new(self.cx, &mut self.buffer)) } #[inline] - fn end(mut self) -> Result { + fn end_pack(mut self) -> Result { static PAD: [u8; 1024] = [0; 1024]; let buffer = self.buffer.into_inner(); @@ -412,55 +416,75 @@ where } } -impl<'a, W, const F: Options, C> SequenceEncoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> SequenceEncoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeNext<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeElement<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_element(&mut self) -> Result, C::Error> { Ok(WireEncoder::new(self.cx, self.writer.borrow_mut())) } #[inline] - fn end(self) -> Result { + fn end_sequence(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEncoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> TupleEncoder for WireEncoder<'a, W, OPT, C> +where + C: ?Sized + Context, + W: Writer, +{ + type Cx = C; + type Ok = (); + type EncodeTupleField<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + + #[inline] + fn encode_tuple_field(&mut self) -> Result, C::Error> { + SequenceEncoder::encode_element(self) + } + + #[inline] + fn end_tuple(self) -> Result { + SequenceEncoder::end_sequence(self) + } +} + +impl<'a, W, const OPT: Options, C> MapEncoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeEntry<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapEntry<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_entry(&mut self) -> Result, C::Error> { + fn encode_map_entry(&mut self) -> Result, C::Error> { Ok(WireEncoder::new(self.cx, self.writer.borrow_mut())) } #[inline] - fn end(self) -> Result { + fn end_map(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEntriesEncoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> MapEntriesEncoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeMapEntryKey<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeMapEntryValue<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapEntryKey<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeMapEntryValue<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_map_entry_key(&mut self) -> Result, C::Error> { @@ -473,20 +497,20 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entries(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> MapEntryEncoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> MapEntryEncoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeMapKey<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeMapValue<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeMapKey<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeMapValue<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_map_key(&mut self) -> Result, C::Error> { @@ -499,40 +523,40 @@ where } #[inline] - fn end(self) -> Result { + fn end_map_entry(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> StructEncoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> StructEncoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeField<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeStructField<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] - fn encode_field(&mut self) -> Result, C::Error> { - MapEncoder::encode_entry(self) + fn encode_struct_field(&mut self) -> Result, C::Error> { + MapEncoder::encode_map_entry(self) } #[inline] - fn end(self) -> Result { + fn end_struct(self) -> Result { Ok(()) } } -impl<'a, W, const F: Options, C> StructFieldEncoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> StructFieldEncoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeFieldName<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeFieldValue<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeFieldName<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeFieldValue<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_field_name(&mut self) -> Result, C::Error> { @@ -545,20 +569,20 @@ where } #[inline] - fn end(self) -> Result { - MapEntryEncoder::end(self) + fn end_field(self) -> Result { + MapEntryEncoder::end_map_entry(self) } } -impl<'a, W, const F: Options, C> VariantEncoder for WireEncoder<'a, W, F, C> +impl<'a, W, const OPT: Options, C> VariantEncoder for WireEncoder<'a, W, OPT, C> where C: ?Sized + Context, W: Writer, { type Cx = C; type Ok = (); - type EncodeTag<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; - type EncodeValue<'this> = WireEncoder<'a, W::Mut<'this>, F, C> where Self: 'this; + type EncodeTag<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; + type EncodeValue<'this> = WireEncoder<'a, W::Mut<'this>, OPT, C> where Self: 'this; #[inline] fn encode_tag(&mut self) -> Result, C::Error> { @@ -571,14 +595,18 @@ where } #[inline] - fn end(self) -> Result { + fn end_variant(self) -> Result { Ok(()) } } /// Encode a length prefix. #[inline] -fn encode_prefix(cx: &C, mut writer: W, len: usize) -> Result<(), C::Error> +fn encode_prefix( + cx: &C, + mut writer: W, + len: usize, +) -> Result<(), C::Error> where C: ?Sized + Context, W: Writer, @@ -587,7 +615,7 @@ where writer.write_byte(cx, tag.byte())?; if !embedded { - musli_common::int::encode_usize::<_, _, F>(cx, writer, len)?; + musli_common::int::encode_usize::<_, _, OPT>(cx, writer, len)?; } Ok(()) diff --git a/crates/musli-wire/src/encoding.rs b/crates/musli-wire/src/encoding.rs index a64845b19..4b3dd6434 100644 --- a/crates/musli-wire/src/encoding.rs +++ b/crates/musli-wire/src/encoding.rs @@ -100,7 +100,7 @@ where } /// Setting up encoding with parameters. -pub struct Encoding { +pub struct Encoding { _marker: marker::PhantomData, } @@ -146,9 +146,9 @@ impl Encoding { } } -impl Encoding { +impl Encoding { /// Change the mode of the encoding. - pub const fn with_mode(self) -> Encoding { + pub const fn with_mode(self) -> Encoding { Encoding { _marker: marker::PhantomData, } @@ -172,15 +172,19 @@ impl Encoding { } } - musli_common::encoding_impls!(M, WireEncoder::<_, F, _>::new, WireDecoder::<_, F, _>::new); + musli_common::encoding_impls!( + M, + WireEncoder::<_, OPT, _>::new, + WireDecoder::<_, OPT, _>::new + ); musli_common::encoding_from_slice_impls!(M, WireDecoder::<_, F>::new); } -impl Clone for Encoding { +impl Clone for Encoding { #[inline] fn clone(&self) -> Self { *self } } -impl Copy for Encoding {} +impl Copy for Encoding {} diff --git a/crates/musli-wire/src/test.rs b/crates/musli-wire/src/test.rs index 2b3627dc3..6c132ffde 100644 --- a/crates/musli-wire/src/test.rs +++ b/crates/musli-wire/src/test.rs @@ -33,7 +33,7 @@ where where D: Decoder<'de, Mode = M>, { - decoder.decode_pack_fn(|pack| { + decoder.decode_pack(|pack| { let tag = pack.decode_next()?.decode()?; let value = pack.decode_next()?.decode()?; Ok(Self { tag, value }) diff --git a/crates/musli-wire/src/wire_int.rs b/crates/musli-wire/src/wire_int.rs index 4b4957dda..87178dacc 100644 --- a/crates/musli-wire/src/wire_int.rs +++ b/crates/musli-wire/src/wire_int.rs @@ -10,7 +10,7 @@ use crate::writer::Writer; /// Governs how usize lengths are encoded into a [Writer]. #[inline] -pub(crate) fn encode_length( +pub(crate) fn encode_length( cx: &C, mut writer: W, value: usize, @@ -19,7 +19,7 @@ where C: ?Sized + Context, W: Writer, { - match crate::options::length::() { + match crate::options::length::() { crate::options::Integer::Variable => { if value.is_smaller_than(DATA_MASK) { writer.write_byte(cx, Tag::new(Kind::Continuation, value.as_byte()).byte()) @@ -29,8 +29,8 @@ where } } _ => { - let bo = crate::options::byteorder::(); - let width = crate::options::length_width::(); + let bo = crate::options::byteorder::(); + let width = crate::options::length_width::(); let bytes = 1u8 << width as u8; writer.write_byte(cx, Tag::new(Kind::Prefix, bytes).byte())?; @@ -51,7 +51,7 @@ where /// Governs how usize lengths are decoded from a [Reader]. #[inline] -pub(crate) fn decode_length<'de, C, R, const F: Options>( +pub(crate) fn decode_length<'de, C, R, const OPT: Options>( cx: &C, mut reader: R, ) -> Result @@ -59,7 +59,7 @@ where C: ?Sized + Context, R: Reader<'de>, { - match crate::options::length::() { + match crate::options::length::() { crate::options::Integer::Variable => { let tag = Tag::from_byte(reader.read_byte(cx)?); @@ -74,8 +74,8 @@ where } } _ => { - let bo = crate::options::byteorder::(); - let width = crate::options::length_width::(); + let bo = crate::options::byteorder::(); + let width = crate::options::length_width::(); let bytes = 1u8 << width as u8; let tag = Tag::from_byte(reader.read_byte(cx)?); @@ -104,7 +104,7 @@ where /// Governs how unsigned integers are encoded into a [Writer]. #[inline] -pub(crate) fn encode_unsigned( +pub(crate) fn encode_unsigned( cx: &C, mut writer: W, value: T, @@ -114,7 +114,7 @@ where W: Writer, T: UnsignedOps, { - match crate::options::integer::() { + match crate::options::integer::() { crate::options::Integer::Variable => { if value.is_smaller_than(DATA_MASK) { writer.write_byte(cx, Tag::new(Kind::Continuation, value.as_byte()).byte()) @@ -124,7 +124,7 @@ where } } _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); writer.write_byte(cx, Tag::new(Kind::Prefix, T::BYTES).byte())?; value.write_bytes(cx, writer, bo) } @@ -133,7 +133,7 @@ where /// Governs how unsigned integers are decoded from a [Reader]. #[inline] -pub(crate) fn decode_unsigned<'de, C, R, T, const F: Options>( +pub(crate) fn decode_unsigned<'de, C, R, T, const OPT: Options>( cx: &C, mut reader: R, ) -> Result @@ -142,7 +142,7 @@ where R: Reader<'de>, T: UnsignedOps, { - match crate::options::integer::() { + match crate::options::integer::() { crate::options::Integer::Variable => { let tag = Tag::from_byte(reader.read_byte(cx)?); @@ -157,7 +157,7 @@ where } } _ => { - let bo = crate::options::byteorder::(); + let bo = crate::options::byteorder::(); if Tag::from_byte(reader.read_byte(cx)?) != Tag::new(Kind::Prefix, T::BYTES) { return Err(cx.message("Expected fixed integer")); @@ -170,7 +170,7 @@ where /// Governs how signed integers are encoded into a [Writer]. #[inline] -pub(crate) fn encode_signed( +pub(crate) fn encode_signed( cx: &C, writer: W, value: T, @@ -182,12 +182,12 @@ where T::Unsigned: UnsignedOps, { let value = zig::encode(value); - encode_unsigned::(cx, writer, value) + encode_unsigned::(cx, writer, value) } /// Governs how signed integers are decoded from a [Reader]. #[inline] -pub(crate) fn decode_signed<'de, C, R, T, const F: Options>( +pub(crate) fn decode_signed<'de, C, R, T, const OPT: Options>( cx: &C, reader: R, ) -> Result @@ -197,6 +197,6 @@ where T: Signed, T::Unsigned: UnsignedOps, { - let value = decode_unsigned::(cx, reader)?; + let value = decode_unsigned::(cx, reader)?; Ok(zig::decode(value)) } diff --git a/crates/musli/src/compat.rs b/crates/musli/src/compat.rs index 251a9db00..8fc563384 100644 --- a/crates/musli/src/compat.rs +++ b/crates/musli/src/compat.rs @@ -34,7 +34,7 @@ impl<'de, M> Decode<'de, M> for Sequence<()> { where D: Decoder<'de>, { - decoder.decode_sequence_fn(|_| Ok(Self(()))) + decoder.decode_sequence(|_| Ok(Self(()))) } } diff --git a/crates/musli/src/de/decoder.rs b/crates/musli/src/de/decoder.rs index bc5dadf4f..786595d78 100644 --- a/crates/musli/src/de/decoder.rs +++ b/crates/musli/src/de/decoder.rs @@ -6,9 +6,13 @@ use crate::de::{NumberVisitor, StructDecoder, TypeHint, ValueVisitor, Visitor}; use crate::expecting::{self, Expecting}; use crate::Context; -use super::{AsDecoder, Decode, MapDecoder, PackDecoder, SequenceDecoder, VariantDecoder}; +use super::{ + AsDecoder, Decode, MapDecoder, MapEntriesDecoder, PackDecoder, SequenceDecoder, + StructFieldsDecoder, TupleDecoder, VariantDecoder, +}; /// Trait governing the implementation of a decoder. +#[must_use = "Decoders must be consumed through one of its decode_* methods"] pub trait Decoder<'de>: Sized { /// Context associated with the decoder. type Cx: ?Sized + Context; @@ -25,17 +29,21 @@ pub trait Decoder<'de>: Sized { type DecodeBuffer: AsDecoder; /// Decoder returned by [`Decoder::decode_option`]. type DecodeSome: Decoder<'de, Cx = Self::Cx, Error = Self::Error, Mode = Self::Mode>; - /// Decoder returned by [`Decoder::decode_pack`]. + /// Decoder used by [`Decoder::decode_pack`]. type DecodePack: PackDecoder<'de, Cx = Self::Cx>; /// Decoder returned by [`Decoder::decode_sequence`]. type DecodeSequence: SequenceDecoder<'de, Cx = Self::Cx>; - /// Decoder returned by [`Decoder::decode_tuple`]. - type DecodeTuple: PackDecoder<'de, Cx = Self::Cx>; - /// Decoder returned by [`Decoder::decode_map`]. + /// Decoder used by [`Decoder::decode_tuple`]. + type DecodeTuple: TupleDecoder<'de, Cx = Self::Cx>; + /// Decoder used by [`Decoder::decode_map`]. type DecodeMap: MapDecoder<'de, Cx = Self::Cx>; + /// Decoder returned by [`Decoder::decode_map_entries`]. + type DecodeMapEntries: MapEntriesDecoder<'de, Cx = Self::Cx>; /// Decoder returned by [`Decoder::decode_struct`]. type DecodeStruct: StructDecoder<'de, Cx = Self::Cx>; - /// Decoder returned by [`Decoder::decode_variant`]. + /// Decoder used by [`Decoder::decode_struct_fields`]. + type DecodeStructFields: StructFieldsDecoder<'de, Cx = Self::Cx>; + /// Decoder used by [`Decoder::decode_variant`]. type DecodeVariant: VariantDecoder<'de, Cx = Self::Cx>; /// This is a type argument used to hint to any future implementor that they @@ -163,23 +171,21 @@ pub trait Decoder<'de>: Sized { /// { /// let mut buffer = decoder.decode_buffer()?; /// - /// let mut st = buffer.as_decoder()?.decode_map()?; + /// let discriminant = buffer.as_decoder()?.decode_map(|st| { + /// loop { + /// let Some(mut e) = st.decode_entry()? else { + /// return Err(cx.missing_variant_tag("MyVariantType")); + /// }; /// - /// let discriminant = loop { - /// let Some(mut e) = st.decode_entry()? else { - /// return Err(cx.missing_variant_tag("MyVariantType")); - /// }; + /// let found = e.decode_map_key()?.decode_string(musli::utils::visit_owned_fn("a string that is 'type'", |string: &str| { + /// Ok(string == "type") + /// }))?; /// - /// let found = e.decode_map_key()?.decode_string(musli::utils::visit_owned_fn("a string that is 'type'", |string: &str| { - /// Ok(string == "type") - /// }))?; - /// - /// if found { - /// break e.decode_map_value()?.decode()?; + /// if found { + /// break Ok(e.decode_map_value()?.decode()?); + /// } /// } - /// }; - /// - /// st.end()?; + /// })?; /// /// match discriminant { /// 0 => Ok(MyVariantType::Variant1), @@ -1032,8 +1038,8 @@ pub trait Decoder<'de>: Sized { /// ``` /// use std::fmt; /// - /// use musli::Context; - /// use musli::de::{Decode, Decoder, ValueVisitor}; + /// use musli::{Context, Decode, Decoder}; + /// use musli::de::ValueVisitor; /// # struct StringReference<'de> { data: &'de str } /// /// impl<'de, M> Decode<'de, M> for StringReference<'de> { @@ -1148,60 +1154,8 @@ pub trait Decoder<'de>: Sized { /// Implementing manually: /// /// ``` - /// use musli::Context; - /// use musli::de::{Decode, Decoder, PackDecoder}; - /// # struct PackedStruct { field: u32, data: [u8; 128] } - /// - /// impl<'de, M> Decode<'de, M> for PackedStruct { - /// #[inline] - /// fn decode(cx: &D::Cx, decoder: D) -> Result - /// where - /// D: Decoder<'de>, - /// { - /// let mut pack = decoder.decode_pack()?; - /// let field = pack.next()?; - /// let data = pack.next()?; - /// pack.end()?; - /// - /// Ok(Self { field, data }) - /// } - /// } - /// ``` - #[inline] - fn decode_pack(self) -> Result::Error> { - Err(self.cx().message(expecting::unsupported_type( - &expecting::Pack, - ExpectingWrapper::new(&self), - ))) - } - - /// Construct an unpack that can decode more than one element at a time. - /// - /// This hints to the format that it should attempt to decode all of the - /// elements in the packed sequence from an as compact format as possible - /// compatible with what's being returned by - /// [Encoder::pack][crate::Encoder::encode_pack]. - /// - /// # Examples - /// - /// Deriving an implementation: - /// - /// ``` - /// use musli::Decode; - /// - /// #[derive(Decode)] - /// #[musli(packed)] - /// struct PackedStruct { - /// field: u32, - /// data: [u8; 128], - /// } - /// ``` - /// - /// Implementing manually: - /// - /// ``` - /// use musli::Context; - /// use musli::de::{Decode, Decoder, PackDecoder}; + /// use musli::{Context, Decode, Decoder}; + /// use musli::de::PackDecoder; /// # struct PackedStruct { field: u32, data: [u8; 128] } /// /// impl<'de, M> Decode<'de, M> for PackedStruct { @@ -1210,7 +1164,7 @@ pub trait Decoder<'de>: Sized { /// where /// D: Decoder<'de>, /// { - /// decoder.decode_pack_fn(|pack| Ok(Self { + /// decoder.decode_pack(|pack| Ok(Self { /// field: pack.next()?, /// data: pack.next()?, /// })) @@ -1218,60 +1172,12 @@ pub trait Decoder<'de>: Sized { /// } /// ``` #[inline] - fn decode_pack_fn(self, f: F) -> Result::Error> + fn decode_pack(self, f: F) -> Result::Error> where F: FnOnce(&mut Self::DecodePack) -> Result::Error>, { - let mut pack = self.decode_pack()?; - let result = f(&mut pack)?; - pack.end()?; - Ok(result) - } - - /// Decode a sequence. - /// - /// # Examples - /// - /// Deriving an implementation: - /// - /// ``` - /// use musli::Decode; - /// - /// #[derive(Decode)] - /// struct VectorField { - /// data: Vec, - /// } - /// ``` - /// - /// Implementing manually: - /// - /// ``` - /// use musli::Context; - /// use musli::de::{Decode, Decoder, SequenceDecoder}; - /// # struct VectorField { data: Vec } - /// - /// impl<'de, M> Decode<'de, M> for VectorField { - /// fn decode(cx: &D::Cx, decoder: D) -> Result - /// where - /// D: Decoder<'de>, - /// { - /// let mut seq = decoder.decode_sequence()?; - /// let mut data = Vec::new(); - /// - /// while let Some(decoder) = seq.decode_next()? { - /// data.push(decoder.decode()?); - /// } - /// - /// seq.end()?; - /// - /// Ok(Self { data }) - /// } - /// } - /// ``` - #[inline] - fn decode_sequence(self) -> Result::Error> { Err(self.cx().message(expecting::unsupported_type( - &expecting::Sequence, + &expecting::Pack, ExpectingWrapper::new(&self), ))) } @@ -1294,8 +1200,8 @@ pub trait Decoder<'de>: Sized { /// Implementing manually: /// /// ``` - /// use musli::Context; - /// use musli::de::{Decode, Decoder, SequenceDecoder}; + /// use musli::{Context, Decode, Decoder}; + /// use musli::de::SequenceDecoder; /// /// struct VectorField { /// data: Vec, @@ -1306,7 +1212,7 @@ pub trait Decoder<'de>: Sized { /// where /// D: Decoder<'de>, /// { - /// decoder.decode_sequence_fn(|seq| { + /// decoder.decode_sequence(|seq| { /// let mut data = Vec::new(); /// /// while let Some(decoder) = seq.decode_next()? { @@ -1319,56 +1225,12 @@ pub trait Decoder<'de>: Sized { /// } /// ``` #[inline] - fn decode_sequence_fn(self, f: F) -> Result::Error> + fn decode_sequence(self, f: F) -> Result::Error> where F: FnOnce(&mut Self::DecodeSequence) -> Result::Error>, { - let mut sequence = self.decode_sequence()?; - let result = f(&mut sequence)?; - sequence.end()?; - Ok(result) - } - - /// Decode a fixed-length sequence of elements of length `len`. - /// - /// # Examples - /// - /// Deriving an implementation: - /// - /// ``` - /// use musli::Decode; - /// - /// #[derive(Decode)] - /// struct TupleStruct(String, u32); - /// ``` - /// - /// Implementing manually: - /// - /// ``` - /// use musli::Context; - /// use musli::de::{Decode, Decoder, PackDecoder}; - /// # struct TupleStruct(String, u32); - /// - /// impl<'de, M> Decode<'de, M> for TupleStruct { - /// fn decode(cx: &D::Cx, decoder: D) -> Result - /// where - /// D: Decoder<'de>, - /// { - /// let mut tuple = decoder.decode_tuple(2)?; - /// let string = tuple.decode_next()?.decode()?; - /// let integer = tuple.decode_next()?.decode()?; - /// tuple.end()?; - /// Ok(Self(string, integer)) - /// } - /// } - /// ``` - #[inline] - fn decode_tuple( - self, - #[allow(unused)] len: usize, - ) -> Result::Error> { Err(self.cx().message(expecting::unsupported_type( - &expecting::Tuple, + &expecting::Sequence, ExpectingWrapper::new(&self), ))) } @@ -1389,8 +1251,8 @@ pub trait Decoder<'de>: Sized { /// Implementing manually: /// /// ``` - /// use musli::Context; - /// use musli::de::{Decode, Decoder, PackDecoder}; + /// use musli::{Context, Decode, Decoder}; + /// use musli::de::TupleDecoder; /// # struct TupleStruct(String, u32); /// /// impl<'de, M> Decode<'de, M> for TupleStruct { @@ -1398,77 +1260,19 @@ pub trait Decoder<'de>: Sized { /// where /// D: Decoder<'de>, /// { - /// decoder.decode_tuple_fn(2, |tuple| { + /// decoder.decode_tuple(2, |tuple| { /// Ok(Self(tuple.next()?, tuple.next()?)) /// }) /// } /// } /// ``` #[inline] - fn decode_tuple_fn(self, len: usize, f: F) -> Result::Error> + fn decode_tuple(self, len: usize, f: F) -> Result::Error> where F: FnOnce(&mut Self::DecodeTuple) -> Result::Error>, { - let mut tuple = self.decode_tuple(len)?; - let result = f(&mut tuple)?; - tuple.end()?; - Ok(result) - } - - /// Decode a map. - /// - /// The length of the map must somehow be determined from the underlying - /// format. - /// - /// # Examples - /// - /// Deriving an implementation: - /// - /// ``` - /// use std::collections::HashMap; - /// - /// use musli::{Context, Decode}; - /// - /// #[derive(Decode)] - /// struct MapStruct { - /// data: HashMap, - /// } - /// ``` - /// - /// Implementing manually: - /// - /// ``` - /// use musli::{Context, Decode, Decoder}; - /// use musli::de::{MapDecoder, MapEntryDecoder}; - /// # use std::collections::HashMap; - /// # struct MapStruct { data: HashMap } - /// - /// impl<'de, M> Decode<'de, M> for MapStruct { - /// fn decode(cx: &D::Cx, decoder: D) -> Result - /// where - /// D: Decoder<'de>, - /// { - /// let mut map = decoder.decode_map()?; - /// let mut data = HashMap::with_capacity(map.size_hint().or_default()); - /// - /// while let Some(mut entry) = map.decode_entry()? { - /// let key = entry.decode_map_key()?.decode()?; - /// let value = entry.decode_map_value()?.decode()?; - /// data.insert(key, value); - /// } - /// - /// map.end()?; - /// - /// Ok(Self { - /// data - /// }) - /// } - /// } - /// ``` - #[inline] - fn decode_map(self) -> Result::Error> { Err(self.cx().message(expecting::unsupported_type( - &expecting::Map, + &expecting::Tuple, ExpectingWrapper::new(&self), ))) } @@ -1508,7 +1312,7 @@ pub trait Decoder<'de>: Sized { /// where /// D: Decoder<'de>, /// { - /// decoder.decode_map_fn(|map| { + /// decoder.decode_map(|map| { /// let mut data = HashMap::with_capacity(map.size_hint().or_default()); /// /// while let Some((key, value)) = map.entry()? { @@ -1521,17 +1325,33 @@ pub trait Decoder<'de>: Sized { /// } /// ``` #[inline] - fn decode_map_fn(self, f: F) -> Result::Error> + fn decode_map(self, f: F) -> Result::Error> where F: FnOnce(&mut Self::DecodeMap) -> Result::Error>, { - let mut map = self.decode_map()?; - let result = f(&mut map)?; - map.end()?; - Ok(result) + Err(self.cx().message(expecting::unsupported_type( + &expecting::Map, + ExpectingWrapper::new(&self), + ))) } - /// Decode a struct which has an expected `len` number of elements. + /// Simplified decoding a map of unknown length. + /// + /// The length of the map must somehow be determined from the underlying + /// format. + #[inline] + fn decode_map_entries(self) -> Result::Error> + where + Self: Sized, + { + Err(self.cx().message(expecting::unsupported_type( + &expecting::MapEntries, + ExpectingWrapper::new(&self), + ))) + } + + /// Decode a struct which has an expected `len` number of elements using a + /// closure. /// /// The `len` indicates how many fields the decoder is *expecting* depending /// on how many fields are present in the underlying struct being decoded, @@ -1565,73 +1385,7 @@ pub trait Decoder<'de>: Sized { /// where /// D: Decoder<'de>, /// { - /// let mut st = decoder.decode_struct(None)?; - /// let mut string = None; - /// let mut integer = None; - /// - /// while let Some(mut field) = st.decode_field()? { - /// // Note: to avoid allocating `decode_string` needs to be used with a visitor. - /// let tag = field.decode_field_name()?.decode::()?; - /// - /// match tag.as_str() { - /// "string" => { - /// string = Some(field.decode_field_value()?.decode()?); - /// } - /// "integer" => { - /// integer = Some(field.decode_field_value()?.decode()?); - /// } - /// tag => { - /// return Err(cx.invalid_field_tag("Struct", tag)); - /// } - /// } - /// } - /// - /// st.end()?; - /// - /// Ok(Self { - /// string: string.ok_or_else(|| cx.expected_tag("Struct", "string"))?, - /// integer: integer.ok_or_else(|| cx.expected_tag("Struct", "integer"))?, - /// }) - /// } - /// } - /// ``` - #[inline] - fn decode_struct( - self, - fields: Option, - ) -> Result::Error> { - Err(self.cx().message(expecting::unsupported_type( - &expecting::Struct, - ExpectingWrapper::new(&self), - ))) - } - - /// Decode a struct which has an expected `len` number of elements using a - /// closure. - /// - /// The `len` indicates how many fields the decoder is *expecting* depending - /// on how many fields are present in the underlying struct being decoded, - /// butit should only be considered advisory. - /// - /// The size of a struct might therefore change from one session to another. - /// - /// # Examples - /// - /// ``` - /// use musli::{Context, Decode, Decoder}; - /// use musli::de::{StructDecoder, StructFieldDecoder}; - /// - /// struct Struct { - /// string: String, - /// integer: u32, - /// } - /// - /// impl<'de, M> Decode<'de, M> for Struct { - /// fn decode(cx: &D::Cx, decoder: D) -> Result - /// where - /// D: Decoder<'de>, - /// { - /// decoder.decode_struct_fn(None, |st| { + /// decoder.decode_struct(None, |st| { /// let mut string = None; /// let mut integer = None; /// @@ -1661,7 +1415,7 @@ pub trait Decoder<'de>: Sized { /// } /// ``` #[inline] - fn decode_struct_fn( + fn decode_struct( self, fields: Option, f: F, @@ -1669,56 +1423,31 @@ pub trait Decoder<'de>: Sized { where F: FnOnce(&mut Self::DecodeStruct) -> Result::Error>, { - let mut st = self.decode_struct(fields)?; - let result = f(&mut st)?; - st.end()?; - Ok(result) + Err(self.cx().message(expecting::unsupported_type( + &expecting::Struct, + ExpectingWrapper::new(&self), + ))) } - /// Return a decoder for a variant. - /// - /// # Examples - /// - /// ``` - /// use musli::{Context, Decode}; - /// use musli::de::{Decoder, VariantDecoder}; - /// - /// enum Enum { - /// Variant1(u32), - /// Variant2(String), - /// } - /// - /// impl<'de, M> Decode<'de, M> for Enum { - /// fn decode(cx: &D::Cx, decoder: D) -> Result - /// where - /// D: Decoder<'de>, - /// { - /// let mut variant = decoder.decode_variant()?; - /// let tag = variant.decode_tag()?.decode()?; + /// Simplified decoding of a struct which has an expected `len` number of + /// elements. /// - /// let this = match tag { - /// 0 => { - /// Self::Variant1(variant.decode_value()?.decode()?) - /// } - /// 1 => { - /// Self::Variant2(variant.decode_value()?.decode()?) - /// } - /// tag => { - /// return Err(cx.invalid_variant_tag("Enum", tag)); - /// } - /// }; + /// The `len` indicates how many fields the decoder is *expecting* depending + /// on how many fields are present in the underlying struct being decoded, + /// butit should only be considered advisory. /// - /// variant.end()?; - /// Ok(this) - /// } - /// } - /// ``` + /// The size of a struct might therefore change from one session to another. #[inline] - fn decode_variant(self) -> Result::Error> { - Err(self.cx().message(expecting::unsupported_type( - &expecting::Variant, - ExpectingWrapper::new(&self), - ))) + fn decode_struct_fields( + self, + fields: Option, + ) -> Result::Error> + where + Self: Sized, + { + Err(self + .cx() + .message("Decoder does not support StructPairs decoding")) } /// Decode a variant using a closure. @@ -1739,7 +1468,7 @@ pub trait Decoder<'de>: Sized { /// where /// D: Decoder<'de>, /// { - /// decoder.decode_variant_fn(|variant| { + /// decoder.decode_variant(|variant| { /// let tag = variant.decode_tag()?.decode()?; /// /// match tag { @@ -1758,14 +1487,14 @@ pub trait Decoder<'de>: Sized { /// } /// ``` #[inline] - fn decode_variant_fn(self, f: F) -> Result::Error> + fn decode_variant(self, f: F) -> Result::Error> where F: FnOnce(&mut Self::DecodeVariant) -> Result::Error>, { - let mut variant = self.decode_variant()?; - let result = f(&mut variant)?; - variant.end()?; - Ok(result) + Err(self.cx().message(expecting::unsupported_type( + &expecting::Variant, + ExpectingWrapper::new(&self), + ))) } /// Decode dynamically through a [`Visitor`]. diff --git a/crates/musli/src/de/map_decoder.rs b/crates/musli/src/de/map_decoder.rs index 3ce37409a..6d3d5046e 100644 --- a/crates/musli/src/de/map_decoder.rs +++ b/crates/musli/src/de/map_decoder.rs @@ -10,17 +10,10 @@ pub trait MapDecoder<'de>: Sized { type DecodeEntry<'this>: MapEntryDecoder<'de, Cx = Self::Cx> where Self: 'this; - /// Decoder for a sequence of map pairs. - type IntoMapEntries: MapEntriesDecoder<'de, Cx = Self::Cx>; - - /// This is a type argument used to hint to any future implementor that they - /// should be using the [`#[musli::map_decoder]`][crate::map_decoder] - /// attribute macro when implementing [`MapDecoder`]. - #[doc(hidden)] - type __UseMusliMapDecoderAttributeMacro; - - /// Return the context associated with the decoder. - fn cx(&self) -> &Self::Cx; + /// Decoder returned by [`MapDecoder::decode_remaining_entries`]. + type DecodeRemainingEntries<'this>: MapEntriesDecoder<'de, Cx = Self::Cx> + where + Self: 'this; /// Get a size hint of known remaining elements. fn size_hint(&self) -> SizeHint; @@ -32,21 +25,6 @@ pub trait MapDecoder<'de>: Sized { &mut self, ) -> Result>, ::Error>; - /// End the pair decoder. - /// - /// If there are any remaining elements in the sequence of pairs, this - /// indicates that they should be flushed. - #[inline] - fn end(mut self) -> Result<(), ::Error> { - // Skip remaining elements. - while let Some(mut item) = self.decode_entry()? { - item.decode_map_key()?.skip()?; - item.skip_map_value()?; - } - - Ok(()) - } - /// Decode the next map entry as a tuple. fn entry(&mut self) -> Result, ::Error> where @@ -63,17 +41,8 @@ pub trait MapDecoder<'de>: Sized { } } - /// Simplified decoding a map of unknown length. - /// - /// The length of the map must somehow be determined from the underlying - /// format. - #[inline] - fn into_map_entries(self) -> Result::Error> - where - Self: Sized, - { - Err(self - .cx() - .message("Decoder does not support MapPairs decoding")) - } + /// Return simplified decoder for remaining entries. + fn decode_remaining_entries( + &mut self, + ) -> Result, ::Error>; } diff --git a/crates/musli/src/de/map_entries_decoder.rs b/crates/musli/src/de/map_entries_decoder.rs index 55c21b268..e5420d354 100644 --- a/crates/musli/src/de/map_entries_decoder.rs +++ b/crates/musli/src/de/map_entries_decoder.rs @@ -9,6 +9,7 @@ use super::Decoder; /// /// If you do not intend to implement this, then serde compatibility for your /// format might be degraded. +#[must_use = "Must call end_map_entries to complete decoding"] pub trait MapEntriesDecoder<'de>: Sized { /// Context associated with the decoder. type Cx: ?Sized + Context; @@ -51,18 +52,6 @@ pub trait MapEntriesDecoder<'de>: Sized { /// The boolean returned indicates if the value was skipped or not. fn skip_map_entry_value(&mut self) -> Result::Error>; - /// End pair decoding. - #[inline] - fn end(mut self) -> Result<(), ::Error> { - loop { - let Some(item) = self.decode_map_entry_key()? else { - break; - }; - - item.skip()?; - self.skip_map_entry_value()?; - } - - Ok(()) - } + /// End entries decoding. + fn end_map_entries(self) -> Result<(), ::Error>; } diff --git a/crates/musli/src/de/mod.rs b/crates/musli/src/de/mod.rs index 6e731c74b..454d53e36 100644 --- a/crates/musli/src/de/mod.rs +++ b/crates/musli/src/de/mod.rs @@ -43,6 +43,9 @@ pub use self::number_visitor::NumberVisitor; mod pack_decoder; pub use self::pack_decoder::PackDecoder; +mod tuple_decoder; +pub use self::tuple_decoder::TupleDecoder; + mod sequence_decoder; pub use self::sequence_decoder::SequenceDecoder; diff --git a/crates/musli/src/de/pack_decoder.rs b/crates/musli/src/de/pack_decoder.rs index e5d2b86c3..75e438767 100644 --- a/crates/musli/src/de/pack_decoder.rs +++ b/crates/musli/src/de/pack_decoder.rs @@ -20,11 +20,6 @@ pub trait PackDecoder<'de> { #[must_use = "Decoders must be consumed"] fn decode_next(&mut self) -> Result, ::Error>; - /// Stop decoding the current pack. - /// - /// This is required to call after a pack has finished decoding. - fn end(self) -> Result<(), ::Error>; - /// Unpack a value of the given type. #[inline] fn next(&mut self) -> Result::Error> diff --git a/crates/musli/src/de/sequence_decoder.rs b/crates/musli/src/de/sequence_decoder.rs index 3cf594292..3f11093c2 100644 --- a/crates/musli/src/de/sequence_decoder.rs +++ b/crates/musli/src/de/sequence_decoder.rs @@ -24,18 +24,6 @@ pub trait SequenceDecoder<'de>: Sized { fn decode_next(&mut self) -> Result>, ::Error>; - /// Stop decoding the current sequence. - /// - /// This is required to call after a sequence has finished decoding. - #[inline] - fn end(mut self) -> Result<(), ::Error> { - while let Some(item) = self.decode_next()? { - item.skip()?; - } - - Ok(()) - } - /// Decode the next element of the given type. #[inline] fn next(&mut self) -> Result, ::Error> diff --git a/crates/musli/src/de/struct_decoder.rs b/crates/musli/src/de/struct_decoder.rs index d233e533f..92dcf7dfe 100644 --- a/crates/musli/src/de/struct_decoder.rs +++ b/crates/musli/src/de/struct_decoder.rs @@ -1,6 +1,6 @@ use crate::Context; -use super::{Decoder, SizeHint, StructFieldDecoder, StructFieldsDecoder}; +use super::{SizeHint, StructFieldDecoder}; /// Trait governing how to decode fields in a struct. pub trait StructDecoder<'de>: Sized { @@ -10,17 +10,6 @@ pub trait StructDecoder<'de>: Sized { type DecodeField<'this>: StructFieldDecoder<'de, Cx = Self::Cx> where Self: 'this; - /// Decoder for a sequence of struct pairs. - type IntoStructFields: StructFieldsDecoder<'de, Cx = Self::Cx>; - - /// This is a type argument used to hint to any future implementor that they - /// should be using the [`#[musli::struct_decoder]`][crate::struct_decoder] - /// attribute macro when implementing [`MapDecoder`]. - #[doc(hidden)] - type __UseMusliStructDecoderAttributeMacro; - - /// Access the context associated with the decoder. - fn cx(&self) -> &Self::Cx; /// Get a size hint of known remaining fields. fn size_hint(&self) -> SizeHint; @@ -30,35 +19,4 @@ pub trait StructDecoder<'de>: Sized { fn decode_field( &mut self, ) -> Result>, ::Error>; - - /// End the struct decoder. - /// - /// If there are any remaining elements in the sequence of pairs, this - /// indicates that they should be flushed. - fn end(mut self) -> Result<(), ::Error> { - while let Some(mut item) = self.decode_field()? { - item.decode_field_name()?.skip()?; - item.skip_field_value()?; - } - - Ok(()) - } - - /// Simplified decoding of a struct which has an expected `len` number of - /// elements. - /// - /// The `len` indicates how many fields the decoder is *expecting* depending - /// on how many fields are present in the underlying struct being decoded, - /// butit should only be considered advisory. - /// - /// The size of a struct might therefore change from one session to another. - #[inline] - fn into_struct_fields(self) -> Result::Error> - where - Self: Sized, - { - Err(self - .cx() - .message("Decoder does not support StructPairs decoding")) - } } diff --git a/crates/musli/src/de/struct_fields_decoder.rs b/crates/musli/src/de/struct_fields_decoder.rs index 84cc5f9c6..59d54dfda 100644 --- a/crates/musli/src/de/struct_fields_decoder.rs +++ b/crates/musli/src/de/struct_fields_decoder.rs @@ -52,5 +52,5 @@ pub trait StructFieldsDecoder<'de> { fn skip_struct_field_value(&mut self) -> Result::Error>; /// End pair decoding. - fn end(self) -> Result<(), ::Error>; + fn end_struct_fields(self) -> Result<(), ::Error>; } diff --git a/crates/musli/src/de/tuple_decoder.rs b/crates/musli/src/de/tuple_decoder.rs new file mode 100644 index 000000000..6b2c02f7a --- /dev/null +++ b/crates/musli/src/de/tuple_decoder.rs @@ -0,0 +1,32 @@ +use crate::Context; + +use super::{Decode, Decoder}; + +/// A decoder for tuples. +pub trait TupleDecoder<'de> { + /// Context associated with the decoder. + type Cx: ?Sized + Context; + /// The encoder to use for the tuple element. + type DecodeNext<'this>: Decoder< + 'de, + Cx = Self::Cx, + Error = ::Error, + Mode = ::Mode, + > + where + Self: 'this; + + /// Return decoder to unpack the next element. + #[must_use = "Decoders must be consumed"] + fn decode_next(&mut self) -> Result, ::Error>; + + /// Unpack a value of the given type. + #[inline] + fn next(&mut self) -> Result::Error> + where + Self: Sized, + T: Decode<'de, ::Mode>, + { + self.decode_next()?.decode() + } +} diff --git a/crates/musli/src/de/variant_decoder.rs b/crates/musli/src/de/variant_decoder.rs index 746fb7fb7..667e12b51 100644 --- a/crates/musli/src/de/variant_decoder.rs +++ b/crates/musli/src/de/variant_decoder.rs @@ -40,7 +40,4 @@ pub trait VariantDecoder<'de> { /// /// The boolean returned indicates if the value was skipped or not. fn skip_value(&mut self) -> Result::Error>; - - /// End the pair decoder. - fn end(self) -> Result<(), ::Error>; } diff --git a/crates/musli/src/de/visitor.rs b/crates/musli/src/de/visitor.rs index 8e5005bf3..c922fc05b 100644 --- a/crates/musli/src/de/visitor.rs +++ b/crates/musli/src/de/visitor.rs @@ -214,9 +214,9 @@ pub trait Visitor<'de, C: ?Sized + Context>: Sized { /// Indicates that the visited type is a sequence. #[inline] - fn visit_sequence(self, cx: &C, decoder: D) -> Result + fn visit_sequence(self, cx: &C, decoder: &mut D) -> Result where - D: SequenceDecoder<'de, Cx = C>, + D: ?Sized + SequenceDecoder<'de, Cx = C>, { Err(cx.message(expecting::unsupported_type( &expecting::SequenceWith(decoder.size_hint()), @@ -226,9 +226,9 @@ pub trait Visitor<'de, C: ?Sized + Context>: Sized { /// Indicates that the visited type is a map. #[inline] - fn visit_map(self, cx: &C, decoder: D) -> Result::Error> + fn visit_map(self, cx: &C, decoder: &mut D) -> Result::Error> where - D: MapDecoder<'de, Cx = C>, + D: ?Sized + MapDecoder<'de, Cx = C>, { Err(cx.message(expecting::unsupported_type( &expecting::MapWith(decoder.size_hint()), @@ -265,7 +265,7 @@ pub trait Visitor<'de, C: ?Sized + Context>: Sized { /// Indicates that the visited type is a variant. #[inline] - fn visit_variant(self, cx: &C, _: D) -> Result + fn visit_variant(self, cx: &C, _: &mut D) -> Result where D: VariantDecoder<'de, Cx = C>, { diff --git a/crates/musli/src/en/encoder.rs b/crates/musli/src/en/encoder.rs index e6915b37c..6c678fc84 100644 --- a/crates/musli/src/en/encoder.rs +++ b/crates/musli/src/en/encoder.rs @@ -6,10 +6,12 @@ use crate::expecting::{self, Expecting}; use crate::Context; use super::{ - Encode, MapEncoder, MapEntriesEncoder, SequenceEncoder, StructEncoder, VariantEncoder, + Encode, MapEncoder, MapEntriesEncoder, PackEncoder, SequenceEncoder, StructEncoder, + TupleEncoder, VariantEncoder, }; /// Trait governing how the encoder works. +#[must_use = "Encoders must be consumed through one of its encode_* methods"] pub trait Encoder: Sized { /// Context associated with the encoder. type Cx: ?Sized + Context; @@ -26,13 +28,13 @@ pub trait Encoder: Sized { where U: 'this + Context; /// A simple pack that packs a sequence of elements. - type EncodePack: SequenceEncoder; + type EncodePack: PackEncoder; /// Encoder returned when encoding an optional value which is present. type EncodeSome: Encoder; /// The type of a sequence encoder. type EncodeSequence: SequenceEncoder; /// The type of a tuple encoder. - type EncodeTuple: SequenceEncoder; + type EncodeTuple: TupleEncoder; /// The type of a map encoder. type EncodeMap: MapEncoder; /// Streaming encoder for map pairs. @@ -42,7 +44,7 @@ pub trait Encoder: Sized { /// Encoder for a struct variant. type EncodeVariant: VariantEncoder; /// Specialized encoder for a tuple variant. - type EncodeTupleVariant: SequenceEncoder; + type EncodeTupleVariant: TupleEncoder; /// Specialized encoder for a struct variant. type EncodeStructVariant: StructEncoder; @@ -1056,7 +1058,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{SequenceEncoder}; + /// use musli::en::PackEncoder; /// /// struct PackedStruct { /// field: u32, @@ -1069,9 +1071,9 @@ pub trait Encoder: Sized { /// E: Encoder, /// { /// let mut pack = encoder.encode_pack()?; - /// pack.encode_next()?.encode(self.field)?; - /// pack.encode_next()?.encode(self.data)?; - /// pack.end() + /// pack.encode_packed()?.encode(self.field)?; + /// pack.encode_packed()?.encode(self.data)?; + /// pack.end_pack() /// } /// } /// ``` @@ -1089,7 +1091,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{SequenceEncoder}; + /// use musli::en::PackEncoder; /// /// struct PackedStruct { /// field: u32, @@ -1102,8 +1104,8 @@ pub trait Encoder: Sized { /// E: Encoder, /// { /// encoder.encode_pack_fn(|pack| { - /// pack.encode_next()?.encode(self.field)?; - /// pack.encode_next()?.encode(&self.data)?; + /// pack.encode_packed()?.encode(self.field)?; + /// pack.encode_packed()?.encode(&self.data)?; /// Ok(()) /// }) /// } @@ -1116,7 +1118,7 @@ pub trait Encoder: Sized { { let mut pack = self.encode_pack()?; f(&mut pack)?; - pack.end() + pack.end_pack() } /// Encode a sequence with a known length `len`. @@ -1145,7 +1147,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{SequenceEncoder}; + /// use musli::en::SequenceEncoder; /// # struct MyType { data: Vec } /// /// impl Encode for MyType { @@ -1159,7 +1161,7 @@ pub trait Encoder: Sized { /// seq.push(element)?; /// } /// - /// seq.end() + /// seq.end_sequence() /// } /// } /// ``` @@ -1180,7 +1182,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{SequenceEncoder}; + /// use musli::en::SequenceEncoder; /// # struct MyType { data: Vec } /// /// impl Encode for MyType { @@ -1209,7 +1211,7 @@ pub trait Encoder: Sized { { let mut seq = self.encode_sequence(len)?; f(&mut seq)?; - seq.end() + seq.end_sequence() } /// Encode a tuple with a known length `len`. @@ -1226,7 +1228,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{SequenceEncoder}; + /// use musli::en::TupleEncoder; /// /// struct PackedTuple(u32, [u8; 128]); /// @@ -1236,9 +1238,9 @@ pub trait Encoder: Sized { /// E: Encoder, /// { /// let mut tuple = encoder.encode_tuple(2)?; - /// tuple.encode_next()?.encode(self.0)?; - /// tuple.encode_next()?.encode(&self.1)?; - /// tuple.end() + /// tuple.encode_tuple_field()?.encode(self.0)?; + /// tuple.encode_tuple_field()?.encode(&self.1)?; + /// tuple.end_tuple() /// } /// } /// ``` @@ -1264,7 +1266,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{SequenceEncoder}; + /// use musli::en::TupleEncoder; /// /// struct PackedTuple(u32, [u8; 128]); /// @@ -1274,8 +1276,8 @@ pub trait Encoder: Sized { /// E: Encoder, /// { /// encoder.encode_tuple_fn(2, |tuple| { - /// tuple.encode_next()?.encode(self.0)?; - /// tuple.encode_next()?.encode(&self.1)?; + /// tuple.encode_tuple_field()?.encode(self.0)?; + /// tuple.encode_tuple_field()?.encode(&self.1)?; /// Ok(()) /// }) /// } @@ -1288,7 +1290,7 @@ pub trait Encoder: Sized { { let mut tuple = self.encode_tuple(len)?; f(&mut tuple)?; - tuple.end() + tuple.end_tuple() } /// Encode a map with a known length `len`. @@ -1311,7 +1313,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{MapEncoder}; + /// use musli::en::MapEncoder; /// # struct Struct { name: String, age: u32 } /// /// impl Encode for Struct { @@ -1322,7 +1324,7 @@ pub trait Encoder: Sized { /// let mut map = encoder.encode_map(2)?; /// map.insert_entry("name", &self.name)?; /// map.insert_entry("age", self.age)?; - /// map.end() + /// map.end_map() /// } /// } /// ``` @@ -1340,7 +1342,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{MapEncoder}; + /// use musli::en::MapEncoder; /// /// struct Struct { /// name: String, @@ -1367,7 +1369,7 @@ pub trait Encoder: Sized { { let mut map = self.encode_map(len)?; f(&mut map)?; - map.end() + map.end_map() } /// Encode a map through pairs with a known length `len`. @@ -1376,7 +1378,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{MapEntriesEncoder}; + /// use musli::en::MapEntriesEncoder; /// /// struct Struct { /// name: String, @@ -1396,7 +1398,7 @@ pub trait Encoder: Sized { /// // Key and value encoding as a stream. /// m.encode_map_entry_key()?.encode("age")?; /// m.encode_map_entry_value()?.encode(self.age)?; - /// m.end() + /// m.end_map_entries() /// } /// } /// ``` @@ -1417,7 +1419,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{StructEncoder}; + /// use musli::en::StructEncoder; /// /// struct Struct { /// name: String, @@ -1430,9 +1432,9 @@ pub trait Encoder: Sized { /// E: Encoder, /// { /// let mut st = encoder.encode_struct(2)?; - /// st.insert_field("name", &self.name)?; - /// st.insert_field("age", self.age)?; - /// st.end() + /// st.insert_struct_field("name", &self.name)?; + /// st.insert_struct_field("age", self.age)?; + /// st.end_struct() /// } /// } /// ``` @@ -1453,7 +1455,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{StructEncoder}; + /// use musli::en::StructEncoder; /// /// struct Struct { /// name: String, @@ -1466,8 +1468,8 @@ pub trait Encoder: Sized { /// E: Encoder, /// { /// encoder.encode_struct_fn(2, |st| { - /// st.insert_field("name", &self.name)?; - /// st.insert_field("age", self.age)?; + /// st.insert_struct_field("name", &self.name)?; + /// st.insert_struct_field("age", self.age)?; /// Ok(()) /// }) /// } @@ -1484,7 +1486,7 @@ pub trait Encoder: Sized { { let mut st = self.encode_struct(fields)?; f(&mut st)?; - st.end() + st.end_struct() } /// Encode a variant. @@ -1509,7 +1511,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{VariantEncoder, StructEncoder, SequenceEncoder}; + /// use musli::en::{VariantEncoder, TupleEncoder, StructEncoder}; /// # enum Enum { UnitVariant, TupleVariant(String), StructVariant { data: String, age: u32 } } /// /// impl Encode for Enum { @@ -1521,20 +1523,26 @@ pub trait Encoder: Sized { /// /// match self { /// Enum::UnitVariant => { - /// variant.insert_variant("variant1", ()) + /// variant.insert_variant("UnitVariant", ()) /// } /// Enum::TupleVariant(data) => { - /// variant.insert_variant("variant2", data) + /// variant.encode_tag()?.encode_string("TupleVariant")?; + /// + /// let mut tuple = variant.encode_value()?.encode_tuple(1)?; + /// tuple.push_tuple_field(data)?; + /// tuple.end_tuple()?; + /// + /// variant.end_variant() /// } /// Enum::StructVariant { data, age } => { - /// variant.encode_tag()?.encode_string("variant3")?; + /// variant.encode_tag()?.encode_string("StructVariant")?; /// /// let mut st = variant.encode_value()?.encode_struct(2)?; - /// st.insert_field("data", data)?; - /// st.insert_field("age", age)?; - /// st.end()?; + /// st.insert_struct_field("data", data)?; + /// st.insert_struct_field("age", age)?; + /// st.end_struct()?; /// - /// variant.end() + /// variant.end_variant() /// } /// } /// } @@ -1554,7 +1562,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{VariantEncoder, StructEncoder, SequenceEncoder}; + /// use musli::en::{VariantEncoder, TupleEncoder, StructEncoder}; /// /// enum Enum { /// UnitVariant, @@ -1575,15 +1583,24 @@ pub trait Encoder: Sized { /// encoder.encode_variant()?.insert_variant("variant1", ()) /// } /// Enum::TupleVariant(data) => { - /// encoder.encode_variant()?.insert_variant("variant2", data) + /// encoder.encode_variant_fn(|variant| { + /// variant.encode_tag()?.encode("TupleVariant")?; + /// + /// variant.encode_value()?.encode_tuple_fn(1, |tuple| { + /// tuple.push_tuple_field(data)?; + /// Ok(()) + /// })?; + /// + /// Ok(()) + /// }) /// } /// Enum::StructVariant { data, age } => { /// encoder.encode_variant_fn(|variant| { - /// variant.encode_tag()?.encode_string("variant3")?; + /// variant.encode_tag()?.encode("variant3")?; /// /// variant.encode_value()?.encode_struct_fn(2, |st| { - /// st.insert_field("data", data)?; - /// st.insert_field("age", age)?; + /// st.insert_struct_field("data", data)?; + /// st.insert_struct_field("age", age)?; /// Ok(()) /// })?; /// @@ -1601,7 +1618,7 @@ pub trait Encoder: Sized { { let mut variant = self.encode_variant()?; f(&mut variant)?; - variant.end() + variant.end_variant() } /// Simplified encoding for a unit variant. @@ -1633,7 +1650,7 @@ pub trait Encoder: Sized { /// { /// match self { /// Enum::UnitVariant => { - /// encoder.encode_unit_variant(&"variant1") + /// encoder.encode_unit_variant("variant1") /// } /// } /// } @@ -1644,10 +1661,11 @@ pub trait Encoder: Sized { where T: ?Sized + Encode<::Mode>, { - let mut variant = self.encode_variant()?; - variant.encode_tag()?.encode(tag)?; - variant.encode_value()?.encode_unit()?; - variant.end() + self.encode_variant_fn(|variant| { + variant.encode_tag()?.encode(tag)?; + variant.encode_value()?.encode_unit()?; + Ok(()) + }) } /// Simplified encoding for a tuple variant. @@ -1669,7 +1687,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{VariantEncoder, StructEncoder, SequenceEncoder}; + /// use musli::en::TupleEncoder; /// # enum Enum { TupleVariant(String) } /// /// impl Encode for Enum { @@ -1679,9 +1697,9 @@ pub trait Encoder: Sized { /// { /// match self { /// Enum::TupleVariant(data) => { - /// let mut variant = encoder.encode_tuple_variant(&"variant2", 1)?; - /// variant.push(data)?; - /// variant.end() + /// let mut variant = encoder.encode_tuple_variant("variant2", 1)?; + /// variant.push_tuple_field(data)?; + /// variant.end_tuple() /// } /// } /// } @@ -1724,7 +1742,7 @@ pub trait Encoder: Sized { /// /// ``` /// use musli::{Encode, Encoder}; - /// use musli::en::{VariantEncoder, StructEncoder, SequenceEncoder}; + /// use musli::en::StructEncoder; /// # enum Enum { StructVariant { data: String, age: u32 } } /// /// impl Encode for Enum { @@ -1734,10 +1752,10 @@ pub trait Encoder: Sized { /// { /// match self { /// Enum::StructVariant { data, age } => { - /// let mut variant = encoder.encode_struct_variant(&"variant3", 2)?; - /// variant.insert_field("data", data)?; - /// variant.insert_field("age", age)?; - /// variant.end() + /// let mut variant = encoder.encode_struct_variant("variant3", 2)?; + /// variant.insert_struct_field("data", data)?; + /// variant.insert_struct_field("age", age)?; + /// variant.end_struct() /// } /// } /// } diff --git a/crates/musli/src/en/map_encoder.rs b/crates/musli/src/en/map_encoder.rs index 59ef50b35..448e29782 100644 --- a/crates/musli/src/en/map_encoder.rs +++ b/crates/musli/src/en/map_encoder.rs @@ -9,15 +9,17 @@ pub trait MapEncoder { /// Result type of the encoder. type Ok; /// Encode the next pair. - type EncodeEntry<'this>: MapEntryEncoder + type EncodeMapEntry<'this>: MapEntryEncoder where Self: 'this; /// Encode the next pair. - fn encode_entry(&mut self) -> Result, ::Error>; + fn encode_map_entry( + &mut self, + ) -> Result, ::Error>; /// Finish encoding pairs. - fn end(self) -> Result::Error>; + fn end_map(self) -> Result::Error>; /// Insert a pair immediately. #[inline] @@ -27,7 +29,7 @@ pub trait MapEncoder { F: Encode<::Mode>, S: Encode<::Mode>, { - self.encode_entry()?.insert_entry(key, value)?; + self.encode_map_entry()?.insert_entry(key, value)?; Ok(()) } } diff --git a/crates/musli/src/en/map_entries_encoder.rs b/crates/musli/src/en/map_entries_encoder.rs index bcdca8f3d..ed401b5be 100644 --- a/crates/musli/src/en/map_entries_encoder.rs +++ b/crates/musli/src/en/map_entries_encoder.rs @@ -45,8 +45,8 @@ pub trait MapEntriesEncoder { &mut self, ) -> Result, ::Error>; - /// Stop encoding this pair. - fn end(self) -> Result::Error>; + /// Complete encoding map entries. + fn end_map_entries(self) -> Result::Error>; /// Insert the pair immediately. #[inline] diff --git a/crates/musli/src/en/map_entry_encoder.rs b/crates/musli/src/en/map_entry_encoder.rs index 1373133fe..65d454bc7 100644 --- a/crates/musli/src/en/map_entry_encoder.rs +++ b/crates/musli/src/en/map_entry_encoder.rs @@ -38,7 +38,7 @@ pub trait MapEntryEncoder { ) -> Result, ::Error>; /// Stop encoding this pair. - fn end(self) -> Result::Error>; + fn end_map_entry(self) -> Result::Error>; /// Insert the pair immediately. #[inline] @@ -54,6 +54,6 @@ pub trait MapEntryEncoder { { self.encode_map_key()?.encode(key)?; self.encode_map_value()?.encode(value)?; - self.end() + self.end_map_entry() } } diff --git a/crates/musli/src/en/mod.rs b/crates/musli/src/en/mod.rs index be77a2520..f0bc0f3a8 100644 --- a/crates/musli/src/en/mod.rs +++ b/crates/musli/src/en/mod.rs @@ -28,6 +28,12 @@ pub use self::encoder::Encoder; mod sequence_encoder; pub use self::sequence_encoder::SequenceEncoder; +mod tuple_encoder; +pub use self::tuple_encoder::TupleEncoder; + +mod pack_encoder; +pub use self::pack_encoder::PackEncoder; + mod map_encoder; pub use self::map_encoder::MapEncoder; diff --git a/crates/musli/src/en/pack_encoder.rs b/crates/musli/src/en/pack_encoder.rs new file mode 100644 index 000000000..955c1cdc1 --- /dev/null +++ b/crates/musli/src/en/pack_encoder.rs @@ -0,0 +1,37 @@ +use crate::Context; + +use super::{Encode, Encoder}; + +/// Trait governing how to encode a pack. +pub trait PackEncoder { + /// Context associated with the encoder. + type Cx: ?Sized + Context; + /// Result type of the encoder. + type Ok; + /// The encoder returned when advancing the pack encoder. + type EncodePacked<'this>: Encoder< + Cx = Self::Cx, + Ok = Self::Ok, + Error = ::Error, + Mode = ::Mode, + > + where + Self: 'this; + + /// Return encoder for the next element. + #[must_use = "Encoder must be consumed"] + fn encode_packed(&mut self) -> Result, ::Error>; + + /// Finish encoding the pack. + fn end_pack(self) -> Result::Error>; + + /// Push an element into the pack. + #[inline] + fn push(&mut self, value: T) -> Result<(), ::Error> + where + T: Encode<::Mode>, + { + self.encode_packed()?.encode(value)?; + Ok(()) + } +} diff --git a/crates/musli/src/en/sequence_encoder.rs b/crates/musli/src/en/sequence_encoder.rs index d711558e0..cbc9a6357 100644 --- a/crates/musli/src/en/sequence_encoder.rs +++ b/crates/musli/src/en/sequence_encoder.rs @@ -9,7 +9,7 @@ pub trait SequenceEncoder { /// Result type of the encoder. type Ok; /// The encoder returned when advancing the sequence encoder. - type EncodeNext<'this>: Encoder< + type EncodeElement<'this>: Encoder< Cx = Self::Cx, Ok = Self::Ok, Error = ::Error, @@ -20,10 +20,10 @@ pub trait SequenceEncoder { /// Return encoder for the next element. #[must_use = "Encoder must be consumed"] - fn encode_next(&mut self) -> Result, ::Error>; + fn encode_element(&mut self) -> Result, ::Error>; /// Finish encoding the sequence. - fn end(self) -> Result::Error>; + fn end_sequence(self) -> Result::Error>; /// Push an element into the sequence. #[inline] @@ -31,7 +31,7 @@ pub trait SequenceEncoder { where T: Encode<::Mode>, { - self.encode_next()?.encode(value)?; + self.encode_element()?.encode(value)?; Ok(()) } } diff --git a/crates/musli/src/en/struct_encoder.rs b/crates/musli/src/en/struct_encoder.rs index 6e22dc386..ce0cf8ba8 100644 --- a/crates/musli/src/en/struct_encoder.rs +++ b/crates/musli/src/en/struct_encoder.rs @@ -9,36 +9,42 @@ pub trait StructEncoder { /// Result type of the encoder. type Ok; /// Encoder for the next struct field. - type EncodeField<'this>: StructFieldEncoder + type EncodeStructField<'this>: StructFieldEncoder where Self: 'this; /// Encode the next field. - fn encode_field(&mut self) -> Result, ::Error>; + fn encode_struct_field( + &mut self, + ) -> Result, ::Error>; /// Finish encoding the struct. - fn end(self) -> Result::Error>; + fn end_struct(self) -> Result::Error>; /// Encode the next field using a closure. #[inline] - fn encode_field_fn(&mut self, f: F) -> Result::Error> + fn encode_struct_field_fn(&mut self, f: F) -> Result::Error> where - F: FnOnce(&mut Self::EncodeField<'_>) -> Result::Error>, + F: FnOnce(&mut Self::EncodeStructField<'_>) -> Result::Error>, { - let mut encoder = self.encode_field()?; + let mut encoder = self.encode_struct_field()?; let output = f(&mut encoder)?; - encoder.end()?; + encoder.end_field()?; Ok(output) } /// Insert a field immediately. #[inline] - fn insert_field(&mut self, field: F, value: V) -> Result<(), ::Error> + fn insert_struct_field( + &mut self, + field: F, + value: V, + ) -> Result<(), ::Error> where F: Encode<::Mode>, V: Encode<::Mode>, { - self.encode_field()?.insert_field(field, value)?; + self.encode_struct_field()?.insert_field(field, value)?; Ok(()) } } diff --git a/crates/musli/src/en/struct_field_encoder.rs b/crates/musli/src/en/struct_field_encoder.rs index b889aa695..fb0bc62db 100644 --- a/crates/musli/src/en/struct_field_encoder.rs +++ b/crates/musli/src/en/struct_field_encoder.rs @@ -40,7 +40,7 @@ pub trait StructFieldEncoder { ) -> Result, ::Error>; /// Stop encoding this field. - fn end(self) -> Result::Error>; + fn end_field(self) -> Result::Error>; /// Insert the pair immediately. #[inline] @@ -56,6 +56,6 @@ pub trait StructFieldEncoder { { self.encode_field_name()?.encode(name)?; self.encode_field_value()?.encode(value)?; - self.end() + self.end_field() } } diff --git a/crates/musli/src/en/tuple_encoder.rs b/crates/musli/src/en/tuple_encoder.rs new file mode 100644 index 000000000..41962625f --- /dev/null +++ b/crates/musli/src/en/tuple_encoder.rs @@ -0,0 +1,39 @@ +use crate::Context; + +use super::{Encode, Encoder}; + +/// Trait governing how to encode a tuple. +pub trait TupleEncoder { + /// Context associated with the encoder. + type Cx: ?Sized + Context; + /// Result type of the encoder. + type Ok; + /// The encoder returned when advancing the tuple encoder. + type EncodeTupleField<'this>: Encoder< + Cx = Self::Cx, + Ok = Self::Ok, + Error = ::Error, + Mode = ::Mode, + > + where + Self: 'this; + + /// Return encoder for the next element. + #[must_use = "Encoder must be consumed"] + fn encode_tuple_field( + &mut self, + ) -> Result, ::Error>; + + /// Push an element into the tuple. + #[inline] + fn push_tuple_field(&mut self, value: T) -> Result<(), ::Error> + where + T: Encode<::Mode>, + { + self.encode_tuple_field()?.encode(value)?; + Ok(()) + } + + /// Finish encoding the tuple. + fn end_tuple(self) -> Result::Error>; +} diff --git a/crates/musli/src/en/variant_encoder.rs b/crates/musli/src/en/variant_encoder.rs index 706fb31d9..781c5f4f8 100644 --- a/crates/musli/src/en/variant_encoder.rs +++ b/crates/musli/src/en/variant_encoder.rs @@ -3,6 +3,7 @@ use crate::Context; use super::{Encode, Encoder}; /// Trait governing how to encode a variant. +#[must_use = "Must call end_variant to finish encoding"] pub trait VariantEncoder { /// Context associated with the encoder. type Cx: ?Sized + Context; @@ -36,7 +37,7 @@ pub trait VariantEncoder { fn encode_value(&mut self) -> Result, ::Error>; /// End the variant encoder. - fn end(self) -> Result::Error>; + fn end_variant(self) -> Result::Error>; /// Insert the variant immediately. #[inline] @@ -52,6 +53,6 @@ pub trait VariantEncoder { { self.encode_tag()?.encode(tag)?; self.encode_value()?.encode(value)?; - self.end() + self.end_variant() } } diff --git a/crates/musli/src/expecting.rs b/crates/musli/src/expecting.rs index 8bb60bc37..fb1a8fee1 100644 --- a/crates/musli/src/expecting.rs +++ b/crates/musli/src/expecting.rs @@ -138,6 +138,7 @@ expect! { pub(crate) Bytes("bytes"); pub(crate) Array("array"); pub(crate) Map("map"); + pub(crate) MapEntries("map entries"); pub(crate) Option("option"); pub(crate) Tuple("tuple"); pub(crate) Sequence("sequence"); diff --git a/crates/musli/src/impls/alloc.rs b/crates/musli/src/impls/alloc.rs index b10fef159..bd84db8c7 100644 --- a/crates/musli/src/impls/alloc.rs +++ b/crates/musli/src/impls/alloc.rs @@ -29,6 +29,9 @@ use crate::en::{ use crate::internal::size_hint; use crate::Context; +#[cfg(feature = "std")] +use super::PlatformTag; + impl Encode for String { #[inline] fn encode(&self, cx: &E::Cx, encoder: E) -> Result @@ -244,7 +247,7 @@ macro_rules! sequence { where D: Decoder<'de, Mode = M>, { - decoder.decode_sequence_fn(|$access| { + decoder.decode_sequence(|$access| { let mut out = $factory; let mut index = 0; @@ -313,10 +316,7 @@ macro_rules! map { { encoder.encode_map_fn(self.len(), |map| { for (k, v) in self { - let mut entry = map.encode_entry()?; - entry.encode_map_key()?.encode(k)?; - entry.encode_map_value()?.encode(v)?; - entry.end()?; + map.insert_entry(k, v)?; } Ok(()) @@ -338,10 +338,10 @@ macro_rules! map { encoder.encode_map_fn(self.len(), |map| { for (k, v) in self { $cx.enter_map_key(k); - let mut entry = map.encode_entry()?; + let mut entry = map.encode_map_entry()?; entry.encode_map_key()?.encode(k)?; entry.encode_map_value()?.encode(v)?; - entry.end()?; + entry.end_map_entry()?; $cx.leave_map_key(); } @@ -361,7 +361,7 @@ macro_rules! map { where D: Decoder<'de, Mode = M>, { - decoder.decode_map_fn(|$access| { + decoder.decode_map(|$access| { let mut out = $with_capacity; while let Some((key, value)) = $access.entry()? { @@ -384,7 +384,7 @@ macro_rules! map { where D: Decoder<'de, Mode = M>, { - decoder.decode_map_fn(|$access| { + decoder.decode_map(|$access| { let mut out = $with_capacity; while let Some(mut entry) = $access.decode_entry()? { @@ -542,20 +542,12 @@ macro_rules! smart_pointer { smart_pointer!(Box, Arc, Rc); -#[cfg(feature = "std")] -#[derive(Encode, Decode)] -#[musli(crate)] -enum PlatformTag { - Unix, - Windows, -} - #[cfg(all(feature = "std", any(unix, windows)))] #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))] impl Encode for OsStr { #[cfg(unix)] #[inline] - fn encode(&self, cx: &E::Cx, encoder: E) -> Result + fn encode(&self, _: &E::Cx, encoder: E) -> Result where E: Encoder, { @@ -563,10 +555,11 @@ impl Encode for OsStr { use crate::en::VariantEncoder; - let mut variant = encoder.encode_variant()?; - PlatformTag::Unix.encode(cx, variant.encode_tag()?)?; - self.as_bytes().encode_bytes(cx, variant.encode_value()?)?; - variant.end() + encoder.encode_variant_fn(|variant| { + variant.encode_tag()?.encode(PlatformTag::Unix)?; + variant.encode_value()?.encode_bytes(self.as_bytes())?; + Ok(()) + }) } #[cfg(windows)] @@ -575,27 +568,27 @@ impl Encode for OsStr { where E: Encoder, { - use crate::en::VariantEncoder; - use crate::Buf; use std::os::windows::ffi::OsStrExt; - let mut variant = encoder.encode_variant()?; - let tag = variant.encode_tag()?; + use crate::en::VariantEncoder; + use crate::Buf; - PlatformTag::Windows.encode(cx, tag)?; + encoder.encode_variant_fn(|variant| { + variant.encode_tag()?.encode(PlatformTag::Windows)?; - let Some(mut buf) = cx.alloc() else { - return Err(cx.message("Failed to allocate buffer")); - }; + let Some(mut buf) = cx.alloc() else { + return Err(cx.message("Failed to allocate buffer")); + }; - for w in self.encode_wide() { - if !buf.write(&w.to_le_bytes()) { - return Err(cx.message("Failed to write to buffer")); + for w in self.encode_wide() { + if !buf.write(&w.to_le_bytes()) { + return Err(cx.message("Failed to write to buffer")); + } } - } - buf.as_slice().encode_bytes(cx, variant.encode_value()?)?; - variant.end() + variant.encode_value()?.encode_bytes(buf.as_slice())?; + Ok(()) + }) } } @@ -603,11 +596,11 @@ impl Encode for OsStr { #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))] impl Encode for OsString { #[inline] - fn encode(&self, cx: &E::Cx, encoder: E) -> Result + fn encode(&self, _: &E::Cx, encoder: E) -> Result where E: Encoder, { - self.as_os_str().encode(cx, encoder) + encoder.encode(self.as_os_str()) } } @@ -621,60 +614,56 @@ impl<'de, M> Decode<'de, M> for OsString { { use crate::de::VariantDecoder; - let mut variant = decoder.decode_variant()?; - let tag = variant.decode_tag()?.decode()?; + decoder.decode_variant(|variant| { + let tag = variant.decode_tag()?.decode::()?; - match tag { - #[cfg(not(unix))] - PlatformTag::Unix => Err(cx.message("Unsupported OsString::Unix variant")), - #[cfg(unix)] - PlatformTag::Unix => { - use std::os::unix::ffi::OsStringExt; - - let bytes = variant.decode_value()?.decode()?; - variant.end()?; - Ok(OsString::from_vec(bytes)) - } - #[cfg(not(windows))] - PlatformTag::Windows => Err(cx.message("Unsupported OsString::Windows variant")), - #[cfg(windows)] - PlatformTag::Windows => { - use std::os::windows::ffi::OsStringExt; - - struct Visitor; - - impl<'de, C> ValueVisitor<'de, C, [u8]> for Visitor - where - C: ?Sized + Context, - { - type Ok = OsString; + match tag { + #[cfg(not(unix))] + PlatformTag::Unix => Err(cx.message("Unsupported OsString::Unix variant")), + #[cfg(unix)] + PlatformTag::Unix => { + use std::os::unix::ffi::OsStringExt; + Ok(OsString::from_vec(variant.decode_value()?.decode()?)) + } + #[cfg(not(windows))] + PlatformTag::Windows => Err(cx.message("Unsupported OsString::Windows variant")), + #[cfg(windows)] + PlatformTag::Windows => { + use std::os::windows::ffi::OsStringExt; + + struct Visitor; + + impl<'de, C> ValueVisitor<'de, C, [u8]> for Visitor + where + C: ?Sized + Context, + { + type Ok = OsString; + + #[inline] + fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "a literal byte reference") + } - #[inline] - fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "a literal byte reference") - } + #[inline] + fn visit_ref(self, _: &C, bytes: &[u8]) -> Result { + let mut buf = Vec::with_capacity(bytes.len() / 2); - #[inline] - fn visit_ref(self, _: &C, bytes: &[u8]) -> Result { - let mut buf = Vec::with_capacity(bytes.len() / 2); + for pair in bytes.chunks_exact(2) { + let &[a, b] = pair else { + continue; + }; - for pair in bytes.chunks_exact(2) { - let &[a, b] = pair else { - continue; - }; + buf.push(u16::from_le_bytes([a, b])); + } - buf.push(u16::from_le_bytes([a, b])); + Ok(OsString::from_wide(&buf)) } - - Ok(OsString::from_wide(&buf)) } - } - let os_string = variant.decode_value()?.decode_bytes(Visitor)?; - variant.end()?; - Ok(os_string) + variant.decode_value()?.decode_bytes(Visitor) + } } - } + }) } } diff --git a/crates/musli/src/impls/mod.rs b/crates/musli/src/impls/mod.rs index 56d94d6c6..8c3b85abf 100644 --- a/crates/musli/src/impls/mod.rs +++ b/crates/musli/src/impls/mod.rs @@ -18,6 +18,15 @@ use crate::de::{Decode, DecodeBytes, Decoder, ValueVisitor, VariantDecoder}; use crate::en::{Encode, EncodeBytes, Encoder, SequenceEncoder, VariantEncoder}; use crate::Context; +/// Platform tag used by certain platform-specific implementations. +#[cfg(feature = "std")] +#[derive(Encode, Decode)] +#[musli(crate)] +enum PlatformTag { + Unix, + Windows, +} + impl Encode for () { #[inline] fn encode(&self, _: &E::Cx, encoder: E) -> Result @@ -154,7 +163,7 @@ where { encoder.encode_sequence_fn(N, |seq| { for value in self.iter() { - seq.encode_next()?.encode(value)?; + seq.encode_element()?.encode(value)?; } Ok(()) @@ -298,18 +307,18 @@ where where E: Encoder, { - let mut seq = encoder.encode_sequence(self.len())?; - - let mut index = 0; - - for value in self { - cx.enter_sequence_index(index); - seq.encode_next()?.encode(value)?; - cx.leave_sequence_index(); - index = index.wrapping_add(index); - } + encoder.encode_sequence_fn(self.len(), |seq| { + let mut index = 0; + + for value in self { + cx.enter_sequence_index(index); + seq.encode_element()?.encode(value)?; + cx.leave_sequence_index(); + index = index.wrapping_add(index); + } - seq.end() + Ok(()) + }) } } @@ -411,17 +420,14 @@ where where D: Decoder<'de, Mode = M>, { - let mut variant = decoder.decode_variant()?; + decoder.decode_variant(|variant| { + let tag = variant.decode_tag()?.decode()?; - let tag = variant.decode_tag()?.decode()?; - - let this = match tag { - ResultTag::Ok => Ok(variant.decode_value()?.decode()?), - ResultTag::Err => Err(variant.decode_value()?.decode()?), - }; - - variant.end()?; - Ok(this) + Ok(match tag { + ResultTag::Ok => Ok(variant.decode_value()?.decode()?), + ResultTag::Err => Err(variant.decode_value()?.decode()?), + }) + }) } } diff --git a/crates/musli/src/impls/net.rs b/crates/musli/src/impls/net.rs index 453750fe1..654d7f828 100644 --- a/crates/musli/src/impls/net.rs +++ b/crates/musli/src/impls/net.rs @@ -1,7 +1,7 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use crate::de::{Decode, Decoder, PackDecoder, VariantDecoder}; -use crate::en::{Encode, Encoder, SequenceEncoder, VariantEncoder}; +use crate::en::{Encode, Encoder, PackEncoder, VariantEncoder}; impl Encode for Ipv4Addr { #[inline] @@ -71,16 +71,14 @@ impl<'de, M> Decode<'de, M> for IpAddr { where D: Decoder<'de>, { - let mut variant = decoder.decode_variant()?; - let tag = variant.decode_tag()?.decode()?; + decoder.decode_variant(|variant| { + let tag = variant.decode_tag()?.decode()?; - let this = match tag { - IpAddrTag::Ipv4 => Self::V4(variant.decode_value()?.decode()?), - IpAddrTag::Ipv6 => Self::V6(variant.decode_value()?.decode()?), - }; - - variant.end()?; - Ok(this) + Ok(match tag { + IpAddrTag::Ipv4 => Self::V4(variant.decode_value()?.decode()?), + IpAddrTag::Ipv6 => Self::V6(variant.decode_value()?.decode()?), + }) + }) } } @@ -104,7 +102,7 @@ impl<'de, M> Decode<'de, M> for SocketAddrV4 { where D: Decoder<'de>, { - decoder.decode_pack_fn(|p| Ok(SocketAddrV4::new(p.next()?, p.next()?))) + decoder.decode_pack(|p| Ok(SocketAddrV4::new(p.next()?, p.next()?))) } } @@ -130,7 +128,7 @@ impl<'de, M> Decode<'de, M> for SocketAddrV6 { where D: Decoder<'de>, { - decoder.decode_pack_fn(|p| Ok(Self::new(p.next()?, p.next()?, p.next()?, p.next()?))) + decoder.decode_pack(|p| Ok(Self::new(p.next()?, p.next()?, p.next()?, p.next()?))) } } @@ -162,15 +160,13 @@ impl<'de, M> Decode<'de, M> for SocketAddr { where D: Decoder<'de>, { - let mut variant = decoder.decode_variant()?; - let tag = variant.decode_tag()?.decode()?; + decoder.decode_variant(|variant| { + let tag = variant.decode_tag()?.decode()?; - let this = match tag { - SocketAddrTag::V4 => Self::V4(variant.decode_value()?.decode()?), - SocketAddrTag::V6 => Self::V6(variant.decode_value()?.decode()?), - }; - - variant.end()?; - Ok(this) + Ok(match tag { + SocketAddrTag::V4 => Self::V4(variant.decode_value()?.decode()?), + SocketAddrTag::V6 => Self::V6(variant.decode_value()?.decode()?), + }) + }) } } diff --git a/crates/musli/src/impls/range.rs b/crates/musli/src/impls/range.rs index fd96c2932..7792d7efd 100644 --- a/crates/musli/src/impls/range.rs +++ b/crates/musli/src/impls/range.rs @@ -1,6 +1,6 @@ use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; -use crate::en::SequenceEncoder; +use crate::en::TupleEncoder; use crate::{Decode, Decoder, Encode, Encoder}; macro_rules! implement { @@ -16,7 +16,7 @@ macro_rules! implement { E: Encoder, { encoder.encode_tuple_fn($count, |tuple| { - $(tuple.encode_next()?.encode(&self.$field)?;)* + $(tuple.encode_tuple_field()?.encode(&self.$field)?;)* Ok(()) }) } @@ -50,7 +50,7 @@ macro_rules! implement_new { E: Encoder, { encoder.encode_tuple_fn($count, |tuple| { - $(tuple.encode_next()?.encode(self.$field())?;)* + $(tuple.encode_tuple_field()?.encode(self.$field())?;)* Ok(()) }) } diff --git a/crates/musli/src/impls/tuples.rs b/crates/musli/src/impls/tuples.rs index c373fa2e6..3bd6aa781 100644 --- a/crates/musli/src/impls/tuples.rs +++ b/crates/musli/src/impls/tuples.rs @@ -1,8 +1,8 @@ //! Implementations for variously lengthed tuples. use crate::compat::Packed; -use crate::de::{Decode, Decoder, PackDecoder}; -use crate::en::{Encode, Encoder, SequenceEncoder}; +use crate::de::{Decode, Decoder, PackDecoder, TupleDecoder}; +use crate::en::{Encode, Encoder, PackEncoder, TupleEncoder}; macro_rules! count { (_) => { 1 }; @@ -46,11 +46,12 @@ macro_rules! declare { where E: Encoder, { - let mut pack = encoder.encode_tuple(count!($ident0 $($ident)*))?; - let ($ident0, $($ident),*) = self; - pack.encode_next()?.encode($ident0)?; - $(pack.encode_next()?.encode($ident)?;)* - pack.end() + encoder.encode_tuple_fn(count!($ident0 $($ident)*), |tuple| { + let ($ident0, $($ident),*) = self; + tuple.encode_tuple_field()?.encode($ident0)?; + $(tuple.encode_tuple_field()?.encode($ident)?;)* + Ok(()) + }) } } @@ -60,11 +61,11 @@ macro_rules! declare { where D: Decoder<'de, Mode = M>, { - let mut tuple = decoder.decode_tuple(count!($ident0 $($ident)*))?; - let $ident0 = tuple.decode_next()?.decode()?; - $(let $ident = tuple.decode_next()?.decode()?;)* - tuple.end()?; - Ok(($ident0, $($ident),*)) + decoder.decode_tuple(count!($ident0 $($ident)*), |tuple| { + let $ident0 = tuple.decode_next()?.decode()?; + $(let $ident = tuple.decode_next()?.decode()?;)* + Ok(($ident0, $($ident),*)) + }) } } @@ -75,10 +76,11 @@ macro_rules! declare { E: Encoder, { let Packed(($ident0, $($ident),*)) = self; - let mut pack = encoder.encode_pack()?; - pack.encode_next()?.encode($ident0)?; - $(pack.encode_next()?.encode($ident)?;)* - pack.end() + encoder.encode_pack_fn(|pack| { + pack.encode_packed()?.encode($ident0)?; + $(pack.encode_packed()?.encode($ident)?;)* + Ok(()) + }) } } @@ -88,7 +90,7 @@ macro_rules! declare { where D: Decoder<'de, Mode = M>, { - decoder.decode_pack_fn(|pack| { + decoder.decode_pack(|pack| { let $ident0 = pack.next()?; $(let $ident = pack.next()?;)* Ok(Packed(($ident0, $($ident),*))) diff --git a/crates/musli/src/lib.rs b/crates/musli/src/lib.rs index 9a235d2ce..83710db12 100644 --- a/crates/musli/src/lib.rs +++ b/crates/musli/src/lib.rs @@ -132,17 +132,14 @@ //! where //! D: Decoder<'de, Mode = M>, //! { -//! let mut seq = decoder.decode_sequence()?; -//! let mut data = Vec::with_capacity(seq.size_hint().or_default()); +//! decoder.decode_sequence(|seq| { +//! let mut data = Vec::with_capacity(seq.size_hint().or_default()); //! -//! while let Some(decoder) = seq.decode_next()? { -//! data.push(decoder.decode()?); -//! } +//! while let Some(decoder) = seq.decode_next()? { +//! data.push(decoder.decode()?); +//! } //! -//! seq.end()?; -//! -//! Ok(Self { -//! data +//! Ok(Self { data }) //! }) //! } //! } @@ -528,33 +525,6 @@ pub use musli_macros::encoder; #[doc(inline)] pub use musli_macros::decoder; -/// This is an attribute macro that must be used when implementing -/// [`MapDecoder`]. -/// -/// It is required to use because a [`MapDecoder`] implementation might -/// introduce new associated types in the future, and this is [not yet -/// supported] on a language level in Rust. So this attribute macro polyfills -/// any missing types automatically. -/// -/// [not yet supported]: https://rust-lang.github.io/rfcs/2532-associated-type-defaults.html -/// -/// [`MapDecoder`]: crate::de::MapDecoder -#[doc(inline)] -pub use musli_macros::map_decoder; - -/// This is an attribute macro that must be used when implementing -/// [`StructDecoder`]. -/// -/// It is required to use because a [`StructDecoder`] implementation might -/// introduce new associated types in the future, and this is [not yet -/// supported] on a language level in Rust. So this attribute macro polyfills -/// any missing types automatically. -/// -/// [not yet supported]: https://rust-lang.github.io/rfcs/2532-associated-type-defaults.html -/// [`StructDecoder`]: crate::de::StructDecoder -#[doc(inline)] -pub use musli_macros::struct_decoder; - /// This is an attribute macro that must be used when implementing a /// [`Visitor`]. /// diff --git a/crates/musli/src/never.rs b/crates/musli/src/never.rs index d7a39644e..4aa097572 100644 --- a/crates/musli/src/never.rs +++ b/crates/musli/src/never.rs @@ -15,11 +15,11 @@ use crate::no_std::ToOwned; use crate::de::{ AsDecoder, Decode, Decoder, MapDecoder, MapEntriesDecoder, MapEntryDecoder, NumberVisitor, PackDecoder, SequenceDecoder, SizeHint, StructDecoder, StructFieldDecoder, StructFieldsDecoder, - ValueVisitor, VariantDecoder, + TupleDecoder, ValueVisitor, VariantDecoder, }; use crate::en::{ - Encode, Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, SequenceEncoder, - StructEncoder, StructFieldEncoder, VariantEncoder, + Encode, Encoder, MapEncoder, MapEntriesEncoder, MapEntryEncoder, PackEncoder, SequenceEncoder, + StructEncoder, StructFieldEncoder, TupleEncoder, VariantEncoder, }; use crate::{Buf, Context}; @@ -108,8 +108,10 @@ impl<'de, C: ?Sized + Context> Decoder<'de> for Never<(), C> { type DecodeSequence = Self; type DecodeTuple = Self; type DecodeMap = Self; + type DecodeMapEntries = Self; type DecodeSome = Self; type DecodeStruct = Self; + type DecodeStructFields = Self; type DecodeVariant = Self; type __UseMusliDecoderAttributeMacro = (); @@ -192,7 +194,7 @@ impl<'de, C: ?Sized + Context> MapEntriesDecoder<'de> for Never<(), C> { } #[inline] - fn end(self) -> Result<(), C::Error> { + fn end_map_entries(self) -> Result<(), C::Error> { match self._never {} } } @@ -200,34 +202,16 @@ impl<'de, C: ?Sized + Context> MapEntriesDecoder<'de> for Never<(), C> { impl<'de, C: ?Sized + Context> StructDecoder<'de> for Never<(), C> { type Cx = C; type DecodeField<'this> = Self where Self: 'this; - type IntoStructFields = Self; - - type __UseMusliStructDecoderAttributeMacro = (); - - #[inline] - fn cx(&self) -> &Self::Cx { - match self._never {} - } #[inline] fn size_hint(&self) -> SizeHint { match self._never {} } - #[inline] - fn into_struct_fields(self) -> Result { - match self._never {} - } - #[inline] fn decode_field(&mut self) -> Result>, C::Error> { match self._never {} } - - #[inline] - fn end(self) -> Result<(), C::Error> { - match self._never {} - } } impl<'de, C: ?Sized + Context> StructFieldsDecoder<'de> for Never<(), C> { @@ -251,7 +235,7 @@ impl<'de, C: ?Sized + Context> StructFieldsDecoder<'de> for Never<(), C> { } #[inline] - fn end(self) -> Result<(), C::Error> { + fn end_struct_fields(self) -> Result<(), C::Error> { match self._never {} } } @@ -275,24 +259,12 @@ impl<'de, C: ?Sized + Context> VariantDecoder<'de> for Never<(), C> { fn skip_value(&mut self) -> Result { match self._never {} } - - #[inline] - fn end(self) -> Result<(), C::Error> { - match self._never {} - } } impl<'de, C: ?Sized + Context> MapDecoder<'de> for Never<(), C> { type Cx = C; type DecodeEntry<'this> = Self where Self: 'this; - type IntoMapEntries = Self; - - type __UseMusliMapDecoderAttributeMacro = (); - - #[inline] - fn cx(&self) -> &Self::Cx { - match self._never {} - } + type DecodeRemainingEntries<'this> = Self where Self: 'this; #[inline] fn size_hint(&self) -> SizeHint { @@ -305,12 +277,9 @@ impl<'de, C: ?Sized + Context> MapDecoder<'de> for Never<(), C> { } #[inline] - fn end(self) -> Result<(), C::Error> { - match self._never {} - } - - #[inline] - fn into_map_entries(self) -> Result { + fn decode_remaining_entries( + &mut self, + ) -> Result, ::Error> { match self._never {} } } @@ -349,11 +318,6 @@ impl<'de, C: ?Sized + Context> SequenceDecoder<'de> for Never<(), C> { fn decode_next(&mut self) -> Result>, C::Error> { match self._never {} } - - #[inline] - fn end(self) -> Result<(), C::Error> { - match self._never {} - } } impl<'de, C: ?Sized + Context> PackDecoder<'de> for Never<(), C> { @@ -364,9 +328,14 @@ impl<'de, C: ?Sized + Context> PackDecoder<'de> for Never<(), C> { fn decode_next(&mut self) -> Result, C::Error> { match self._never {} } +} + +impl<'de, C: ?Sized + Context> TupleDecoder<'de> for Never<(), C> { + type Cx = C; + type DecodeNext<'this> = Self where Self: 'this; #[inline] - fn end(self) -> Result<(), C::Error> { + fn decode_next(&mut self) -> Result, C::Error> { match self._never {} } } @@ -436,18 +405,50 @@ where } } +impl PackEncoder for Never { + type Cx = C; + type Ok = O; + type EncodePacked<'this> = Self where Self: 'this; + + #[inline] + fn encode_packed(&mut self) -> Result, C::Error> { + match self._never {} + } + + #[inline] + fn end_pack(self) -> Result { + match self._never {} + } +} + impl SequenceEncoder for Never { type Cx = C; type Ok = O; - type EncodeNext<'this> = Self where Self: 'this; + type EncodeElement<'this> = Self where Self: 'this; + + #[inline] + fn encode_element(&mut self) -> Result, C::Error> { + match self._never {} + } + + #[inline] + fn end_sequence(self) -> Result { + match self._never {} + } +} + +impl TupleEncoder for Never { + type Cx = C; + type Ok = O; + type EncodeTupleField<'this> = Self where Self: 'this; #[inline] - fn encode_next(&mut self) -> Result, C::Error> { + fn encode_tuple_field(&mut self) -> Result, C::Error> { match self._never {} } #[inline] - fn end(self) -> Result { + fn end_tuple(self) -> Result { match self._never {} } } @@ -455,14 +456,14 @@ impl SequenceEncoder for Never { impl MapEncoder for Never { type Cx = C; type Ok = O; - type EncodeEntry<'this> = Self where Self: 'this; + type EncodeMapEntry<'this> = Self where Self: 'this; #[inline] - fn encode_entry(&mut self) -> Result, C::Error> { + fn encode_map_entry(&mut self) -> Result, C::Error> { match self._never {} } - fn end(self) -> Result { + fn end_map(self) -> Result { match self._never {} } } @@ -484,7 +485,7 @@ impl MapEntryEncoder for Never { } #[inline] - fn end(self) -> Result { + fn end_map_entry(self) -> Result { match self._never {} } } @@ -506,7 +507,7 @@ impl MapEntriesEncoder for Never { } #[inline] - fn end(self) -> Result { + fn end_map_entries(self) -> Result { match self._never {} } } @@ -514,14 +515,14 @@ impl MapEntriesEncoder for Never { impl StructEncoder for Never { type Cx = C; type Ok = O; - type EncodeField<'this> = Self where Self: 'this; + type EncodeStructField<'this> = Self where Self: 'this; #[inline] - fn encode_field(&mut self) -> Result, C::Error> { + fn encode_struct_field(&mut self) -> Result, C::Error> { match self._never {} } - fn end(self) -> Result { + fn end_struct(self) -> Result { match self._never {} } } @@ -543,7 +544,7 @@ impl StructFieldEncoder for Never { } #[inline] - fn end(self) -> Result { + fn end_field(self) -> Result { match self._never {} } } @@ -565,7 +566,7 @@ impl VariantEncoder for Never { } #[inline] - fn end(self) -> Result { + fn end_variant(self) -> Result { match self._never {} } }