trait_defaults

Attribute Macro trait_defaults 

Source
#[trait_defaults]
Expand description

This is an attribute macro that must be used when implementing the following traits:

It is required to use because these traits 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.

Note that if the Cx or Mode associated types are not specified, they will be defaulted to any type parameters which starts with the uppercase C or M respectively if the trait uses them.

ยงExamples

Implementing Decoder:

use std::fmt;
use std::marker::PhantomData;

use musli_core::Context;
use musli_core::de::Decoder;

struct MyDecoder<C, M> {
    cx: C,
    _marker: PhantomData<M>,
}

#[musli_core::trait_defaults]
impl<'de, C, M> Decoder<'de> for MyDecoder<C, M>
where
    C: Context,
    M: 'static,
{
    #[inline]
    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "32-bit unsigned integers")
    }

    #[inline]
    fn decode_u32(self) -> Result<u32, Self::Error> {
        Ok(42)
    }
}

Implementing UnsizedVisitor:

use std::fmt;

use musli_core::Context;
use musli_core::de::UnsizedVisitor;

struct MyVisitor;

#[musli_core::trait_defaults]
impl<'de, C> UnsizedVisitor<'de, C, [u8]> for MyVisitor
where
    C: Context,
{
    type Ok = ();

    #[inline]
    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "a reference of bytes")
    }
}

Implementing Visitor:

use std::fmt;

use musli_core::Context;
use musli_core::de::Visitor;

struct MyVisitor;

#[musli_core::trait_defaults]
impl<'de, C> Visitor<'de, C> for MyVisitor
where
    C: Context,
{
    type Ok = ();

    #[inline]
    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "a value that can be decoded into dynamic container")
    }
}

Implementing Encoder:

use std::fmt;
use std::marker::PhantomData;

use musli_core::Context;
use musli_core::en::Encoder;

struct MyEncoder<'a, C, M> {
    value: &'a mut Option<u32>,
    cx: C,
    _marker: PhantomData<M>,
}

#[musli_core::trait_defaults]
impl<C, M> Encoder for MyEncoder<'_, C, M>
where
    C: Context,
    M: 'static,
{
    #[inline]
    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "32-bit unsigned integers")
    }

    #[inline]
    fn encode_u32(self, value: u32) -> Result<(), Self::Error> {
        *self.value = Some(value);
        Ok(())
    }
}