epserde 0.12.6

ε-serde is an ε-copy (i.e., almost zero-copy) serialization/deserialization framework
Documentation
/*
 * SPDX-FileCopyrightText: 2023 Inria
 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
 *
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
 */

//! Convenience implementation for references to slices.
//!
//! In theory all types serialized by ε-serde must not contain references.
//! However, we provide a convenience implementation that serializes references
//! to slices as boxed slices.
//!
//! Note, however, that you must deserialize the slice as a vector, even when it
//! appears a type parameter—see the example in the [crate-level
//! documentation](crate).
//!
//! We provide a type hash for `[T]` so that it can be used in
//! [`PhantomData`](`core::marker::PhantomData`).

use core::hash::Hash;

use crate::prelude::*;
use ser::*;

#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, vec::Vec};

// For use with PhantomData
impl<T: TypeHash> TypeHash for [T] {
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
        "[]".hash(hasher);
        T::type_hash(hasher);
    }
}

// For use with PhantomData
impl<T: TypeHash> TypeHash for &[T] {
    fn type_hash(hasher: &mut impl core::hash::Hasher) {
        "&[]".hash(hasher);
        T::type_hash(hasher);
    }
}

unsafe impl<T> CopyType for &[T] {
    type Copy = Deep;
}

impl<T: SerInner> SerInner for &[T]
where
    Box<[T]>: SerInner,
{
    type SerType = Box<[T::SerType]>;
    const IS_ZERO_COPY: bool = false;

    unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
        // SAFETY: the fake boxed slice we create is never used, and we forget
        // it immediately after writing it to the backend.
        let fake = unsafe { Vec::from_raw_parts(self.as_ptr() as *mut T, self.len(), self.len()) }
            .into_boxed_slice();
        unsafe { ser::SerInner::_ser_inner(&fake, backend) }?;
        core::mem::forget(fake);
        Ok(())
    }
}