pub trait Decoder<'de>: Sized {
type Cx: ?Sized + Context<Error = Self::Error, Mode = Self::Mode>;
type Error;
type Mode: 'static;
type WithContext<'this, U>: Decoder<'de, Cx = U, Error = U::Error, Mode = U::Mode>
where U: 'this + Context;
type DecodeBuffer: AsDecoder<Cx = Self::Cx>;
type DecodeSome: Decoder<'de, Cx = Self::Cx, Error = Self::Error, Mode = Self::Mode>;
type DecodePack: SequenceDecoder<'de, Cx = Self::Cx>;
type DecodeSequence: SequenceDecoder<'de, Cx = Self::Cx>;
type DecodeMap: MapDecoder<'de, Cx = Self::Cx>;
type DecodeMapEntries: EntriesDecoder<'de, Cx = Self::Cx>;
type DecodeVariant: VariantDecoder<'de, Cx = Self::Cx>;
Show 39 methods
// Required methods
fn cx(&self) -> &Self::Cx;
fn expecting(&self, f: &mut Formatter<'_>) -> Result;
fn decode<T>(self) -> Result<T, Self::Error>
where T: Decode<'de, Self::Mode>;
fn decode_unsized<T, F, O>(self, f: F) -> Result<O, Self::Error>
where T: ?Sized + DecodeUnsized<'de, Self::Mode>,
F: FnOnce(&T) -> Result<O, <Self::Cx as Context>::Error>;
fn decode_unsized_bytes<T, F, O>(self, f: F) -> Result<O, Self::Error>
where T: ?Sized + DecodeUnsizedBytes<'de, Self::Mode>,
F: FnOnce(&T) -> Result<O, <Self::Cx as Context>::Error>;
// Provided methods
fn with_context<U>(
self,
cx: &U,
) -> Result<Self::WithContext<'_, U>, <Self::Cx as Context>::Error>
where U: Context { ... }
fn skip(self) -> Result<(), <Self::Cx as Context>::Error> { ... }
fn try_skip(self) -> Result<Skip, <Self::Cx as Context>::Error> { ... }
fn decode_buffer(
self,
) -> Result<Self::DecodeBuffer, <Self::Cx as Context>::Error> { ... }
fn decode_empty(self) -> Result<(), <Self::Cx as Context>::Error> { ... }
fn decode_bool(self) -> Result<bool, <Self::Cx as Context>::Error> { ... }
fn decode_char(self) -> Result<char, <Self::Cx as Context>::Error> { ... }
fn decode_u8(self) -> Result<u8, <Self::Cx as Context>::Error> { ... }
fn decode_u16(self) -> Result<u16, <Self::Cx as Context>::Error> { ... }
fn decode_u32(self) -> Result<u32, <Self::Cx as Context>::Error> { ... }
fn decode_u64(self) -> Result<u64, <Self::Cx as Context>::Error> { ... }
fn decode_u128(self) -> Result<u128, <Self::Cx as Context>::Error> { ... }
fn decode_i8(self) -> Result<i8, <Self::Cx as Context>::Error> { ... }
fn decode_i16(self) -> Result<i16, <Self::Cx as Context>::Error> { ... }
fn decode_i32(self) -> Result<i32, <Self::Cx as Context>::Error> { ... }
fn decode_i64(self) -> Result<i64, <Self::Cx as Context>::Error> { ... }
fn decode_i128(self) -> Result<i128, <Self::Cx as Context>::Error> { ... }
fn decode_usize(self) -> Result<usize, <Self::Cx as Context>::Error> { ... }
fn decode_isize(self) -> Result<isize, <Self::Cx as Context>::Error> { ... }
fn decode_f32(self) -> Result<f32, <Self::Cx as Context>::Error> { ... }
fn decode_f64(self) -> Result<f64, <Self::Cx as Context>::Error> { ... }
fn decode_array<const N: usize>(
self,
) -> Result<[u8; N], <Self::Cx as Context>::Error> { ... }
fn decode_bytes<V>(
self,
visitor: V,
) -> Result<V::Ok, <Self::Cx as Context>::Error>
where V: UnsizedVisitor<'de, Self::Cx, [u8]> { ... }
fn decode_string<V>(
self,
visitor: V,
) -> Result<V::Ok, <Self::Cx as Context>::Error>
where V: UnsizedVisitor<'de, Self::Cx, str> { ... }
fn decode_option(
self,
) -> Result<Option<Self::DecodeSome>, <Self::Cx as Context>::Error> { ... }
fn decode_pack<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
where F: FnOnce(&mut Self::DecodePack) -> Result<O, <Self::Cx as Context>::Error> { ... }
fn decode_sequence<F, O>(
self,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
where F: FnOnce(&mut Self::DecodeSequence) -> Result<O, <Self::Cx as Context>::Error> { ... }
fn decode_sequence_hint<F, O>(
self,
hint: &SequenceHint,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
where F: FnOnce(&mut Self::DecodeSequence) -> Result<O, <Self::Cx as Context>::Error> { ... }
fn decode_map<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
where F: FnOnce(&mut Self::DecodeMap) -> Result<O, <Self::Cx as Context>::Error> { ... }
fn decode_map_hint<F, O>(
self,
_: &MapHint,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
where F: FnOnce(&mut Self::DecodeMap) -> Result<O, <Self::Cx as Context>::Error> { ... }
fn decode_map_entries<F, O>(
self,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
where F: FnOnce(&mut Self::DecodeMapEntries) -> Result<O, <Self::Cx as Context>::Error> { ... }
fn decode_variant<F, O>(
self,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
where F: FnOnce(&mut Self::DecodeVariant) -> Result<O, <Self::Cx as Context>::Error> { ... }
fn decode_number<V>(
self,
visitor: V,
) -> Result<V::Ok, <Self::Cx as Context>::Error>
where V: Visitor<'de, Self::Cx> { ... }
fn decode_any<V>(
self,
visitor: V,
) -> Result<V::Ok, <Self::Cx as Context>::Error>
where V: Visitor<'de, Self::Cx> { ... }
}
Expand description
Trait governing the implementation of a decoder.
Required Associated Types§
Sourcetype Cx: ?Sized + Context<Error = Self::Error, Mode = Self::Mode>
type Cx: ?Sized + Context<Error = Self::Error, Mode = Self::Mode>
Context associated with the decoder.
Sourcetype WithContext<'this, U>: Decoder<'de, Cx = U, Error = U::Error, Mode = U::Mode>
where
U: 'this + Context
type WithContext<'this, U>: Decoder<'de, Cx = U, Error = U::Error, Mode = U::Mode> where U: 'this + Context
Decoder
with a different context returned by
Decoder::with_context
Sourcetype DecodeBuffer: AsDecoder<Cx = Self::Cx>
type DecodeBuffer: AsDecoder<Cx = Self::Cx>
Decoder returned by Decoder::decode_buffer
.
Sourcetype DecodeSome: Decoder<'de, Cx = Self::Cx, Error = Self::Error, Mode = Self::Mode>
type DecodeSome: Decoder<'de, Cx = Self::Cx, Error = Self::Error, Mode = Self::Mode>
Decoder returned by Decoder::decode_option
.
Sourcetype DecodePack: SequenceDecoder<'de, Cx = Self::Cx>
type DecodePack: SequenceDecoder<'de, Cx = Self::Cx>
Decoder used by Decoder::decode_pack
.
Sourcetype DecodeSequence: SequenceDecoder<'de, Cx = Self::Cx>
type DecodeSequence: SequenceDecoder<'de, Cx = Self::Cx>
Decoder returned by Decoder::decode_sequence
.
Sourcetype DecodeMap: MapDecoder<'de, Cx = Self::Cx>
type DecodeMap: MapDecoder<'de, Cx = Self::Cx>
Decoder returned by Decoder::decode_map
.
Sourcetype DecodeMapEntries: EntriesDecoder<'de, Cx = Self::Cx>
type DecodeMapEntries: EntriesDecoder<'de, Cx = Self::Cx>
Decoder returned by Decoder::decode_map_entries
.
Sourcetype DecodeVariant: VariantDecoder<'de, Cx = Self::Cx>
type DecodeVariant: VariantDecoder<'de, Cx = Self::Cx>
Decoder used by Decoder::decode_variant
.
Required Methods§
Sourcefn expecting(&self, f: &mut Formatter<'_>) -> Result
fn expecting(&self, f: &mut Formatter<'_>) -> Result
Format the human-readable message that should occur if the decoder was expecting to decode some specific kind of value.
§Examples
use std::fmt;
use std::convert::Infallible;
use musli::Context;
use musli::de::{self, Decoder, Decode};
struct MyDecoder<'a, C: ?Sized> {
cx: &'a C,
}
#[musli::decoder]
impl<'de, C: ?Sized + Context> Decoder<'de> for MyDecoder<'_, C> {
type Cx = C;
fn cx(&self) -> &C {
self.cx
}
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "32-bit unsigned integers")
}
fn decode_u32(self) -> Result<u32, <Self::Cx as Context>::Error> {
Ok(42)
}
}
Sourcefn decode<T>(self) -> Result<T, Self::Error>
fn decode<T>(self) -> Result<T, Self::Error>
Decode the current decoder into the value T
.
This calls the appropriate Decode
implementation for the given type.
Sourcefn decode_unsized<T, F, O>(self, f: F) -> Result<O, Self::Error>
fn decode_unsized<T, F, O>(self, f: F) -> Result<O, Self::Error>
Decode an unsized value by reference through the specified closure.
Provided Methods§
Sourcefn with_context<U>(
self,
cx: &U,
) -> Result<Self::WithContext<'_, U>, <Self::Cx as Context>::Error>where
U: Context,
fn with_context<U>(
self,
cx: &U,
) -> Result<Self::WithContext<'_, U>, <Self::Cx as Context>::Error>where
U: Context,
Construct an decoder with a different context.
Sourcefn try_skip(self) -> Result<Skip, <Self::Cx as Context>::Error>
fn try_skip(self) -> Result<Skip, <Self::Cx as Context>::Error>
This is a variant of Decoder::skip
, but instead of erroring in case
skipping is not supported it must return Skip::Unsupported
.
Sourcefn decode_buffer(
self,
) -> Result<Self::DecodeBuffer, <Self::Cx as Context>::Error>
fn decode_buffer( self, ) -> Result<Self::DecodeBuffer, <Self::Cx as Context>::Error>
Buffer the current decoder into a buffer that can be used multiple times.
Buffering a decoder is necessary when additional introspection is needed to decode a type, but it also means that:
- The entire contents of the decoder needs to be dynamically buffered in memory.
- The in-memory representation might be lossy in some trivial ways. Such as arbitrary precision numbers being punted into a 64-bit float.
§Examples
use musli::{Context, Decode, Decoder};
use musli::de::{AsDecoder, MapDecoder, EntryDecoder};
use musli::mode::Binary;
#[derive(Decode)]
struct Person {
name: String,
age: u32,
}
enum Enum {
Empty,
Person(Person),
}
impl<'de> Decode<'de, Binary> for Enum {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de, Mode = Binary>,
{
let mut buffer = decoder.decode_buffer()?;
let discriminant = buffer.as_decoder()?.decode_map(|st| {
loop {
let Some(mut e) = st.decode_entry()? else {
return Err(cx.missing_variant_tag("Enum"));
};
let found = e.decode_key()?.decode_unsized(|string: &str| {
Ok(string == "type")
})?;
if found {
break Ok(e.decode_value()?.decode()?);
}
}
})?;
match discriminant {
0 => Ok(Enum::Empty),
1 => Ok(Enum::Person(buffer.as_decoder()?.decode()?)),
other => Err(cx.invalid_variant_tag("Enum", &other)),
}
}
}
Sourcefn decode_empty(self) -> Result<(), <Self::Cx as Context>::Error>
fn decode_empty(self) -> Result<(), <Self::Cx as Context>::Error>
Decode a unit.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
struct UnitStruct;
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for UnitType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
decoder.decode_empty()?;
Ok(UnitType)
}
}
Sourcefn decode_bool(self) -> Result<bool, <Self::Cx as Context>::Error>
fn decode_bool(self) -> Result<bool, <Self::Cx as Context>::Error>
Decode a boolean.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct BooleanField {
field: bool,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for BooleanField {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
field: decoder.decode_bool()?,
})
}
}
Sourcefn decode_char(self) -> Result<char, <Self::Cx as Context>::Error>
fn decode_char(self) -> Result<char, <Self::Cx as Context>::Error>
Decode a character.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: char,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_char()?,
})
}
}
Sourcefn decode_u8(self) -> Result<u8, <Self::Cx as Context>::Error>
fn decode_u8(self) -> Result<u8, <Self::Cx as Context>::Error>
Decode a 8-bit unsigned integer (a.k.a. a byte).
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: u8,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_u8()?,
})
}
}
Sourcefn decode_u16(self) -> Result<u16, <Self::Cx as Context>::Error>
fn decode_u16(self) -> Result<u16, <Self::Cx as Context>::Error>
Decode a 16-bit unsigned integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: u16,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_u16()?,
})
}
}
Sourcefn decode_u32(self) -> Result<u32, <Self::Cx as Context>::Error>
fn decode_u32(self) -> Result<u32, <Self::Cx as Context>::Error>
Decode a 32-bit unsigned integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: u32,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_u32()?,
})
}
}
Sourcefn decode_u64(self) -> Result<u64, <Self::Cx as Context>::Error>
fn decode_u64(self) -> Result<u64, <Self::Cx as Context>::Error>
Decode a 64-bit unsigned integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: u64,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_u64()?,
})
}
}
Sourcefn decode_u128(self) -> Result<u128, <Self::Cx as Context>::Error>
fn decode_u128(self) -> Result<u128, <Self::Cx as Context>::Error>
Decode a 128-bit unsigned integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: u128,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_u128()?,
})
}
}
Sourcefn decode_i8(self) -> Result<i8, <Self::Cx as Context>::Error>
fn decode_i8(self) -> Result<i8, <Self::Cx as Context>::Error>
Decode a 8-bit signed integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: i8,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_i8()?,
})
}
}
Sourcefn decode_i16(self) -> Result<i16, <Self::Cx as Context>::Error>
fn decode_i16(self) -> Result<i16, <Self::Cx as Context>::Error>
Decode a 16-bit signed integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: i16,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_i16()?,
})
}
}
Sourcefn decode_i32(self) -> Result<i32, <Self::Cx as Context>::Error>
fn decode_i32(self) -> Result<i32, <Self::Cx as Context>::Error>
Decode a 32-bit signed integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: i32,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_i32()?,
})
}
}
Sourcefn decode_i64(self) -> Result<i64, <Self::Cx as Context>::Error>
fn decode_i64(self) -> Result<i64, <Self::Cx as Context>::Error>
Decode a 64-bit signed integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: i64,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_i64()?,
})
}
}
Sourcefn decode_i128(self) -> Result<i128, <Self::Cx as Context>::Error>
fn decode_i128(self) -> Result<i128, <Self::Cx as Context>::Error>
Decode a 128-bit signed integer.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: i128,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_i128()?,
})
}
}
Sourcefn decode_usize(self) -> Result<usize, <Self::Cx as Context>::Error>
fn decode_usize(self) -> Result<usize, <Self::Cx as Context>::Error>
Decode a usize
.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: usize,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_usize()?,
})
}
}
Sourcefn decode_isize(self) -> Result<isize, <Self::Cx as Context>::Error>
fn decode_isize(self) -> Result<isize, <Self::Cx as Context>::Error>
Decode a isize
.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: isize,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_isize()?,
})
}
}
Sourcefn decode_f32(self) -> Result<f32, <Self::Cx as Context>::Error>
fn decode_f32(self) -> Result<f32, <Self::Cx as Context>::Error>
Decode a 32-bit floating point value.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: f32,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_f32()?,
})
}
}
Sourcefn decode_f64(self) -> Result<f64, <Self::Cx as Context>::Error>
fn decode_f64(self) -> Result<f64, <Self::Cx as Context>::Error>
Decode a 64-bit floating point value.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: f64,
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_f64()?,
})
}
}
Sourcefn decode_array<const N: usize>(
self,
) -> Result<[u8; N], <Self::Cx as Context>::Error>
fn decode_array<const N: usize>( self, ) -> Result<[u8; N], <Self::Cx as Context>::Error>
Decode a fixed-length array.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct MyType {
data: [u8; 128],
}
Implementing manually:
use musli::{Decode, Decoder};
impl<'de, M> Decode<'de, M> for MyType {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
Ok(Self {
data: decoder.decode_array()?,
})
}
}
Sourcefn decode_bytes<V>(
self,
visitor: V,
) -> Result<V::Ok, <Self::Cx as Context>::Error>
fn decode_bytes<V>( self, visitor: V, ) -> Result<V::Ok, <Self::Cx as Context>::Error>
Decode a sequence of bytes whos length is encoded in the payload.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct BytesReference<'de> {
data: &'de [u8],
}
Implementing manually:
use std::fmt;
use musli::{Context, Decode, Decoder};
use musli::de::UnsizedVisitor;
impl<'de, M> Decode<'de, M> for BytesReference<'de> {
#[inline]
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
struct Visitor;
impl<'de, C> UnsizedVisitor<'de, C, [u8]> for Visitor
where
C: ?Sized + Context,
{
type Ok = &'de [u8];
#[inline]
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "a literal byte reference")
}
#[inline]
fn visit_borrowed(self, _: &C, bytes: &'de [u8]) -> Result<Self::Ok, C::Error> {
Ok(bytes)
}
}
Ok(Self {
data: decoder.decode_bytes(Visitor)?,
})
}
}
Sourcefn decode_string<V>(
self,
visitor: V,
) -> Result<V::Ok, <Self::Cx as Context>::Error>
fn decode_string<V>( self, visitor: V, ) -> Result<V::Ok, <Self::Cx as Context>::Error>
Decode a string slice from the current decoder.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct StringReference<'de> {
data: &'de str,
}
Implementing manually:
use std::fmt;
use musli::{Context, Decode, Decoder};
use musli::de::UnsizedVisitor;
impl<'de, M> Decode<'de, M> for StringReference<'de> {
#[inline]
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
struct Visitor;
impl<'de, C> UnsizedVisitor<'de, C, str> for Visitor
where
C: ?Sized + Context,
{
type Ok = &'de str;
#[inline]
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "exact bytes reference")
}
#[inline]
fn visit_borrowed(self, _: &C, bytes: &'de str) -> Result<Self::Ok, C::Error> {
Ok(bytes)
}
}
Ok(Self {
data: decoder.decode_string(Visitor)?,
})
}
}
Sourcefn decode_option(
self,
) -> Result<Option<Self::DecodeSome>, <Self::Cx as Context>::Error>
fn decode_option( self, ) -> Result<Option<Self::DecodeSome>, <Self::Cx as Context>::Error>
Decode an optional value.
§Examples
Deriving an implementation:
use musli::{Context, Decode};
#[derive(Decode)]
struct OptionalField {
data: Option<String>,
}
Implementing manually:
use musli::{Context, Decode, Decoder};
impl<'de, M> Decode<'de, M> for OptionalField {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
let data = if let Some(decoder) = decoder.decode_option()? {
Some(decoder.decode()?)
} else {
None
};
Ok(Self { data })
}
}
Sourcefn decode_pack<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
fn decode_pack<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
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.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
#[musli(packed)]
struct PackedStruct {
field: u32,
data: [u8; 128],
}
Implementing manually:
use musli::{Context, Decode, Decoder};
use musli::de::SequenceDecoder;
impl<'de, M> Decode<'de, M> for PackedStruct {
#[inline]
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
decoder.decode_pack(|pack| Ok(Self {
field: pack.next()?,
data: pack.next()?,
}))
}
}
Sourcefn decode_sequence<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
fn decode_sequence<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
Decode a sequence.
§Examples
Deriving an implementation:
use musli::Decode;
#[derive(Decode)]
struct VectorField {
data: Vec<String>,
}
Implementing manually:
use musli::{Context, Decode, Decoder};
use musli::de::SequenceDecoder;
struct VectorField {
data: Vec<String>,
}
impl<'de, M> Decode<'de, M> for VectorField {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
decoder.decode_sequence(|seq| {
let mut data = Vec::new();
while let Some(decoder) = seq.try_decode_next()? {
data.push(decoder.decode()?);
}
Ok(Self { data })
})
}
}
Deriving an implementation for a tuple:
use musli::Decode;
#[derive(Decode)]
struct TupleStruct(String, u32);
Implementing manually:
use musli::{Context, Decode, Decoder};
use musli::de::SequenceDecoder;
use musli::hint::SequenceHint;
impl<'de, M> Decode<'de, M> for TupleStruct {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
static HINT: SequenceHint = SequenceHint::with_size(2);
decoder.decode_sequence_hint(&HINT, |tuple| {
Ok(Self(tuple.next()?, tuple.next()?))
})
}
}
Sourcefn decode_sequence_hint<F, O>(
self,
hint: &SequenceHint,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
fn decode_sequence_hint<F, O>( self, hint: &SequenceHint, f: F, ) -> Result<O, <Self::Cx as Context>::Error>
Decode a sequence with a hint
indicating its expected characteristics.
§Examples
use musli::{Context, Decode, Decoder};
use musli::de::SequenceDecoder;
use musli::hint::SequenceHint;
impl<'de, M> Decode<'de, M> for TupleStruct {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
static HINT: SequenceHint = SequenceHint::with_size(2);
decoder.decode_sequence_hint(&HINT, |tuple| {
Ok(Self(tuple.next()?, tuple.next()?))
})
}
}
Sourcefn decode_map<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
fn decode_map<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
Decode a map who’s size is not known at compile time.
§Examples
use std::collections::HashMap;
use musli::{Decode, Decoder};
use musli::de::{MapDecoder, EntryDecoder};
impl<'de, M> Decode<'de, M> for MapStruct {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
decoder.decode_map(|map| {
let mut data = HashMap::with_capacity(map.size_hint().or_default());
while let Some((key, value)) = map.entry()? {
data.insert(key, value);
}
Ok(Self { data })
})
}
}
Sourcefn decode_map_hint<F, O>(
self,
_: &MapHint,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
fn decode_map_hint<F, O>( self, _: &MapHint, f: F, ) -> Result<O, <Self::Cx as Context>::Error>
Decode a map using a simplified function.
The length of the map must somehow be determined from the underlying format.
§Examples
Deriving an implementation from a struct:
use std::collections::HashMap;
use musli::Decode;
#[derive(Decode)]
struct Struct {
string: String,
integer: u32,
}
Implementing manually:
use musli::{Context, Decode, Decoder};
use musli::de::{MapDecoder, EntryDecoder};
use musli::hint::MapHint;
struct Struct {
string: String,
integer: u32,
}
impl<'de, M> Decode<'de, M> for Struct {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
static HINT: MapHint = MapHint::with_size(2);
decoder.decode_map_hint(&HINT, |st| {
let mut string = None;
let mut integer = None;
while let Some(mut field) = st.decode_entry()? {
// Note: to avoid allocating `decode_string` needs to be used with a visitor.
let tag = field.decode_key()?.decode::<String>()?;
match tag.as_str() {
"string" => {
string = Some(field.decode_value()?.decode()?);
}
"integer" => {
integer = Some(field.decode_value()?.decode()?);
}
tag => {
return Err(cx.invalid_field_tag("Struct", tag));
}
}
}
Ok(Self {
string: string.ok_or_else(|| cx.expected_tag("Struct", "string"))?,
integer: integer.ok_or_else(|| cx.expected_tag("Struct", "integer"))?,
})
})
}
}
Sourcefn decode_map_entries<F, O>(
self,
f: F,
) -> Result<O, <Self::Cx as Context>::Error>
fn decode_map_entries<F, O>( self, f: F, ) -> Result<O, <Self::Cx as Context>::Error>
Simplified decoding a map of unknown length.
The length of the map must somehow be determined from the underlying format.
Sourcefn decode_variant<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
fn decode_variant<F, O>(self, f: F) -> Result<O, <Self::Cx as Context>::Error>
Decode a variant using a closure.
§Examples
use musli::{Context, Decode};
use musli::de::{Decoder, VariantDecoder};
enum Enum {
Number(u32),
String(String),
}
impl<'de, M> Decode<'de, M> for Enum {
fn decode<D>(cx: &D::Cx, decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
decoder.decode_variant(|variant| {
let tag = variant.decode_tag()?.decode()?;
let value = variant.decode_value()?;
match tag {
0 => Ok(Self::Number(value.decode()?)),
1 => Ok(Self::String(value.decode()?)),
tag => Err(cx.invalid_variant_tag("Enum", &tag)),
}
})
}
}
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.