Skip to main content

pod_wrapper

Macro pod_wrapper 

Source
macro_rules! pod_wrapper {
    ($(unsafe struct $name:ident($type:ty);)*) => { ... };
}
Expand description

Creates a wrapper type for a type that is represented by raw bytes and does not have any invalid bit patterns.

By using pod_wrapper!, you are telling wincode that it can serialize and deserialize a type with a single memcpy – it wont pay attention to things like struct layout, endianness, or anything else that would require validity or bit pattern checks. This is a very strong claim to make, so be sure that your type adheres to those requirements.

Composable with sequence containers or compound types (structs, tuples) for an optimized read/write implementation.

This can be useful outside of sequences as well, for example on newtype structs containing byte arrays with #[repr(transparent)].


💡 Note: as of wincode 0.2.0, pod_wrapper! is no longer needed for types that wincode can determine are “memcpy-safe”.

This includes:

  • u8
  • [u8; N]
  • structs comprised of the above, and;
    • annotated with #[derive(SchemaWrite)] or #[derive(SchemaRead)], and;
    • annotated with #[repr(transparent)] or #[repr(C)].

Similarly, using built-in std collections like Vec<T> or Box<[T]> where T is one of the above will also be automatically optimized.

You’ll really only need to reach for pod_wrapper! when dealing with foreign types for which you cannot derive SchemaWrite or SchemaRead. Or you’re in a controlled scenario where you explicitly want to avoid endianness or layout checks.

§Safety

  • The type must allow any bit pattern (e.g., no bools, no chars, etc.)
  • If used on a compound type like a struct, all fields must be also be memcpy-able, its layout must be guaranteed (via #[repr(transparent)] or #[repr(C)]), and the struct must not have any padding.
  • Must not contain references or pointers (includes types like Vec or Box).
    • Note, you may use pod_wrapper! created types inside types like Vec or Box, e.g., Vec<PodT> or Box<[PodT]>, but using pod_wrapper! on the outer type is invalid.

§Examples

A repr-transparent newtype struct containing a byte array where you cannot derive SchemaWrite or SchemaRead:

#[derive(Serialize, Deserialize, Clone, Copy)]
#[repr(transparent)]
struct Address([u8; 32]);

wincode::pod_wrapper! {
    unsafe struct PodAddress(Address);
}

#[derive(Serialize, Deserialize, SchemaWrite, SchemaRead)]
struct MyStruct {
    #[wincode(with = "PodAddress")]
    address: Address
}

let my_struct = MyStruct {
    address: Address(array::from_fn(|i| i as u8)),
};
let wincode_bytes = wincode::serialize(&my_struct).unwrap();
let bincode_bytes = bincode::serialize(&my_struct).unwrap();
assert_eq!(wincode_bytes, bincode_bytes);