Skip to content

Conversation

@cpubot
Copy link
Collaborator

@cpubot cpubot commented Nov 13, 2025

We have simple zero-copy support for byte slices (&'de [u8]), but we can provide enough compile time information to make this more robust.

This PR adds a marker trait ZeroCopy that is used to provide blanket SchemaRead implementations for:

  • &'de T where T: SchemaRead<'de> + ZeroCopy
  • &'de [T] where T: SchemaRead<'de> + ZeroCopy

Primitive types that implement ZeroCopy are:

  • u8
  • i8
  • [T; N] where T: ZeroCopy

#[derive(SchemaRead)] will implement ZeroCopy on structs when its TypeMeta is TypeMeta::Static { zero_copy: true }

Vs TypeMeta

#16 introduced TypeMeta which also provides compile-time zero_copy information. So, why do we need this?

TypeMeta is geared for usage inside SchemaWrite and SchemaRead implementations. Implementations can provide optimized compile-time branches depending on a type's TypeMeta. Due to limitations in the type system, TypeMeta is unusable for implementing something like a ZeroCopy marker trait. In particular, constants in generics can't be used to constrain implementations. E.g., we cannot

struct Assert<const B: bool>;
trait IsTrue {}
impl IsTrue for Assert<true> {}

impl<'de, T> ZeroCopy for T 
where 
    T: SchemaRead<'de>,
    Assert<{ matches!(T::TYPE_META, TypeMeta::Static { zero_copy: true, .. }) }>: IsTrue,

And as such we can't do anything similar to provide impl<'de, T> SchemaRead<'de> for T where SchemaRead<'de> ...TypeMeta...

Similarly, we could not use the ZeroCopy marker trait to provide blanket implementations for built in types like Vec, Box, etc. because the compiler limits us to a single blanket implementation for each type, so we'd have to get into newtypes, which would yield a terrible API.

So, there's a bit of duplication between where we advertise zero-copy, but the surface area is small since only u8, i8 and [T;N] are marked zero-copy and it's a relatively small amount of code to support. Users generally wont have to interface with any of these mechanics, so it's just a net win from a user-facing perspective.

@cpubot cpubot force-pushed the schema-read-zero-copy branch from 4d51c8a to 949901b Compare November 13, 2025 16:42
@cpubot cpubot added the v0.2.x Features not required for 0.2.0 release, but tagged for inclusion in subsequent patch releases. label Nov 13, 2025
@cpubot cpubot requested a review from alessandrod November 13, 2025 17:15
@cpubot cpubot marked this pull request as draft November 13, 2025 21:47
@cpubot
Copy link
Collaborator Author

cpubot commented Nov 13, 2025

This needs to include a padding check like #19, marked as a draft until I figure out a way to do that

@cpubot cpubot force-pushed the schema-read-zero-copy branch from 949901b to 0bbfe17 Compare November 14, 2025 00:06
@cpubot cpubot marked this pull request as ready for review November 14, 2025 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.2.x Features not required for 0.2.0 release, but tagged for inclusion in subsequent patch releases.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants