-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support private impls of zerocopy traits #1855
Comments
This can also supplant #1330, since the wrapper type can serve as the utility base type for constructing a safe Then |
The approach I suggested to create an external wrapper type could also be done as a derive macro, which could be less confusing to users as derive macros are incapable of modifying the input item, while also giving more control: Input: #[derive(Debug, zerocopy::Immutable, zerocopy::IntoBytes, zerocopy::Wrapper)]
#[zerocopy_wrapper(
// Name defaults to e.g. `${struct}ZerocopyWrapper`
name = "FooWrapper",
// No scope lookup needed; these are known derive names.
// Support for non-zerocopy derives may be unsupported.
derive(FromBytes, KnownLayout, IntoBytes, Immutable),
// Default visibility of pub(self)
vis = pub(crate),
// Default visibility of pub(self)
inner_vis = pub
)]
#[repr(C)]
pub struct Foo {
x: i32,
num_elems: u32,
values: [u32],
} Generates: #[repr(C)]
pub struct Foo {
x: i32,
num_elems: u32,
values: [u32],
}
// `Debug` impl generated for `Foo`
// `Immutable` impl generated for `Foo`.
// `IntoBytes` impl generated for `Foo`.
#[repr(transparent)]
pub(crate) struct FooWrapper(pub Foo);
// `FromBytes` impl generated for `FooWrapper` but checking against the fields of `Foo`.
// `FromZeros` impl generated for `FooWrapper` but checking against the fields of `Foo`.
// `Immutable` impl generated for `FooWrapper` but checking against the fields of `Foo`.
// `IntoBytes` impl generated for `FooWrapper` but checking against the fields of `Foo`.
// `KnownLayout` impl generated for `FooWrapper` but checking against the fields of `Foo`. Then, using this wrapper, I can write a custom validator for a DST, and there I can write any custom logic I'd like, such as extracting a length and validating it matches the length provided, or extracting a custom length based on the header: impl<'a> TryFrom<&'a [u32]> for &'a Foo {
type Error = Error;
fn try_from(data: &'a [u32]) -> Result<&'a Foo, Error> {
let out = &FooWrapper::ref_from_bytes(data.as_bytes())?.0;
if out.num_elems != out.values.len() {
return Err(Error::BadHeaderLen);
}
Ok(out)
}
} |
Many users ask for the ability to derive a zerocopy trait on their public type without allowing its methods to be called by users outside of the defining module - in other words, for the impl itself to be "private".
Rust doesn't support this natively, but we might be able to emulate it.
Some notes from a conversation with @kupiakos and @jswrenn discussion how to accomplish this.
The text was updated successfully, but these errors were encountered: