devela::_dep::rkyv::with

Trait ArchiveWith

pub trait ArchiveWith<F>
where F: ?Sized,
{ type Archived: Portable; type Resolver; // Required method fn resolve_with( field: &F, resolver: Self::Resolver, out: Place<Self::Archived>, ); }
Available on crate feature dep_rkyv only.
Expand description

A variant of Archive that works with wrappers.

Creating a wrapper allows users to customize how fields are archived easily without changing the unarchived type.

This trait allows wrapper types to transparently change the archive behaviors for struct and enum fields. When a field is serialized, it may use the implementations for the wrapper type and the given field instead of the implementation for the type itself.

Only a single implementation of Archive may be written for each type, but multiple implementations of ArchiveWith can be written for the same type because it is parametric over the wrapper type. This is used with the #[rkyv(with = ..)] macro attribute to provide a more flexible interface for serialization.

§Example

use rkyv::{
    access_unchecked, deserialize,
    rancor::{Error, Fallible, Infallible, ResultExt as _},
    to_bytes,
    with::{ArchiveWith, DeserializeWith, SerializeWith},
    Archive, Archived, Deserialize, Place, Resolver, Serialize,
};

struct Incremented;

impl ArchiveWith<i32> for Incremented {
    type Archived = Archived<i32>;
    type Resolver = Resolver<i32>;

    fn resolve_with(field: &i32, _: (), out: Place<Self::Archived>) {
        let incremented = field + 1;
        incremented.resolve((), out);
    }
}

impl<S> SerializeWith<i32, S> for Incremented
where
    S: Fallible + ?Sized,
    i32: Serialize<S>,
{
    fn serialize_with(
        field: &i32,
        serializer: &mut S,
    ) -> Result<Self::Resolver, S::Error> {
        let incremented = field + 1;
        incremented.serialize(serializer)
    }
}

impl<D> DeserializeWith<Archived<i32>, i32, D> for Incremented
where
    D: Fallible + ?Sized,
    Archived<i32>: Deserialize<i32, D>,
{
    fn deserialize_with(
        field: &Archived<i32>,
        deserializer: &mut D,
    ) -> Result<i32, D::Error> {
        Ok(field.deserialize(deserializer)? - 1)
    }
}

#[derive(Archive, Deserialize, Serialize)]
struct Example {
    #[rkyv(with = Incremented)]
    a: i32,
    // Another i32 field, but not incremented this time
    b: i32,
}

let value = Example { a: 4, b: 9 };

let buf = to_bytes::<Error>(&value).unwrap();

let archived =
    unsafe { access_unchecked::<Archived<Example>>(buf.as_ref()) };
// The wrapped field has been incremented
assert_eq!(archived.a, 5);
// ... and the unwrapped field has not
assert_eq!(archived.b, 9);

let deserialized = deserialize::<Example, Infallible>(archived).always_ok();
// The wrapped field is back to normal
assert_eq!(deserialized.a, 4);
// ... and the unwrapped field is unchanged
assert_eq!(deserialized.b, 9);

Required Associated Types§

type Archived: Portable

The archived type of Self with F.

type Resolver

The resolver of a Self with F.

Required Methods§

fn resolve_with(field: &F, resolver: Self::Resolver, out: Place<Self::Archived>)

Resolves the archived type using a reference to the field type F.

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.

Implementors§

§

impl ArchiveWith<Option<NonZero<i8>>> for Niche

§

impl ArchiveWith<Option<NonZero<i16>>> for Niche

§

impl ArchiveWith<Option<NonZero<i32>>> for Niche

§

impl ArchiveWith<Option<NonZero<i64>>> for Niche

§

impl ArchiveWith<Option<NonZero<i128>>> for Niche

§

impl ArchiveWith<Option<NonZero<isize>>> for Niche

§

impl ArchiveWith<Option<NonZero<u8>>> for Niche

§

impl ArchiveWith<Option<NonZero<u16>>> for Niche

§

impl ArchiveWith<Option<NonZero<u32>>> for Niche

§

impl ArchiveWith<Option<NonZero<u64>>> for Niche

§

impl ArchiveWith<Option<NonZero<u128>>> for Niche

§

impl ArchiveWith<Option<NonZero<usize>>> for Niche

§

impl ArchiveWith<PathBuf> for AsString

§

impl ArchiveWith<OsString> for AsString

§

impl ArchiveWith<SystemTime> for AsUnixTime

§

impl<'a> ArchiveWith<Cow<'a, str>> for AsOwned

§

impl<'a> ArchiveWith<Cow<'a, CStr>> for AsOwned

§

impl<'a, F> ArchiveWith<Cow<'a, F>> for AsOwned
where F: Archive + Clone,

§

type Archived = <F as Archive>::Archived

§

type Resolver = <F as Archive>::Resolver

§

impl<'a, T> ArchiveWith<Cow<'a, [T]>> for AsOwned
where T: Archive + Clone,

§

impl<A, B, K, V> ArchiveWith<BTreeMap<K, V>> for MapKV<A, B>
where A: ArchiveWith<K>, B: ArchiveWith<V>,

§

impl<A, B, K, V, H> ArchiveWith<HashMap<K, V, H>> for MapKV<A, B>
where A: ArchiveWith<K>, B: ArchiveWith<V>, H: Default + BuildHasher,

§

impl<A, B, K, V, H> ArchiveWith<HashMap<K, V, H>> for MapKV<A, B>
where A: ArchiveWith<K>, B: ArchiveWith<V>, H: Default + BuildHasher,

§

impl<A, O> ArchiveWith<Option<O>> for Map<A>
where A: ArchiveWith<O>,

§

impl<A, O> ArchiveWith<Vec<O>> for Map<A>
where A: ArchiveWith<O>,

§

impl<F> ArchiveWith<&F> for Inline
where F: Archive,

§

type Archived = <F as Archive>::Archived

§

type Resolver = <F as Archive>::Resolver

§

impl<F> ArchiveWith<&F> for InlineAsBox
where F: ArchiveUnsized + ?Sized,

§

impl<F> ArchiveWith<Cell<F>> for Unsafe
where F: Archive,

§

type Archived = <F as Archive>::Archived

§

type Resolver = <F as Archive>::Resolver

§

impl<F> ArchiveWith<UnsafeCell<F>> for Unsafe
where F: Archive,

§

type Archived = <F as Archive>::Archived

§

type Resolver = <F as Archive>::Resolver

§

impl<F> ArchiveWith<Mutex<F>> for Lock
where F: Archive,

§

type Archived = <F as Archive>::Archived

§

type Resolver = <F as Archive>::Resolver

§

impl<F> ArchiveWith<RwLock<F>> for Lock
where F: Archive,

§

type Archived = <F as Archive>::Archived

§

type Resolver = <F as Archive>::Resolver

§

impl<F> ArchiveWith<F> for AsBox
where F: ArchiveUnsized + ?Sized,

§

impl<F> ArchiveWith<F> for Identity
where F: Archive,

§

type Archived = <F as Archive>::Archived

§

type Resolver = <F as Archive>::Resolver

§

impl<F> ArchiveWith<F> for Skip

§

type Archived = ()

§

type Resolver = ()

§

impl<K, V> ArchiveWith<BTreeMap<K, V>> for AsVec
where K: Archive, V: Archive,

§

impl<K, V, H> ArchiveWith<HashMap<K, V, H>> for AsVec
where K: Archive, V: Archive,

§

impl<SO> ArchiveWith<AtomicBool> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI8> for AtomicLoad<SO>
where SO: LoadOrdering,

§

type Archived = i8

§

type Resolver = ()

§

impl<SO> ArchiveWith<AtomicI16> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI32> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI64> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicIsize> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU8> for AtomicLoad<SO>
where SO: LoadOrdering,

§

type Archived = u8

§

type Resolver = ()

§

impl<SO> ArchiveWith<AtomicU16> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU32> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU64> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicUsize> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI16_be> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI16_le> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI32_be> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI32_le> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI64_be> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicI64_le> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU16_be> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU16_le> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU32_be> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU32_le> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU64_be> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<SO> ArchiveWith<AtomicU64_le> for AtomicLoad<SO>
where SO: LoadOrdering,

§

impl<T> ArchiveWith<Option<Box<T>>> for Niche

§

impl<T> ArchiveWith<Option<T>> for DefaultNiche

§

impl<T> ArchiveWith<BTreeSet<T>> for AsVec
where T: Archive,

§

impl<T> ArchiveWith<Rc<T>> for Unshare
where T: Archive,

§

type Archived = <T as Archive>::Archived

§

type Resolver = <T as Archive>::Resolver

§

impl<T> ArchiveWith<Arc<T>> for Unshare
where T: Archive,

§

type Archived = <T as Archive>::Archived

§

type Resolver = <T as Archive>::Resolver

§

impl<T, H> ArchiveWith<HashSet<T, H>> for AsVec
where T: Archive,

§

impl<T, N> ArchiveWith<Option<T>> for NicheInto<N>
where T: Archive, N: Niching<<T as Archive>::Archived> + ?Sized,

§

impl<T, W, N> ArchiveWith<Option<T>> for MapNiche<W, N>
where W: ArchiveWith<T> + ?Sized, N: Niching<<W as ArchiveWith<T>>::Archived> + ?Sized,

§

impl<const A: usize> ArchiveWith<AlignedVec<A>> for AsVec