-
Notifications
You must be signed in to change notification settings - Fork 37
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
IntoCtx/TryIntoCtx on borrowed values #46
Comments
So I considered this a while ago since we don’t technically consume the object, but I made it take an owned value because it seemed “right”. That being said are there any downsides to switching to a non owned value ? I don’t think we can do very many optimizations unless it’s a copy value, but then we don’t need the owned value anyway? Anyone else have thoughts ? (Besides this being another breaking change, willglynn is busting up scroll 🤣) For the record I’m pretty much ok with this I think, unless I’m missing something. |
An alternative to note is to add another tryinto method but I suppose we can always do that after (and add another pwrite method); but we can’t do the reverse after the crate is 1.0 |
I've pondered this a bit since my initial writeup, and I can now distill my argument:
The breakage of this change is worth considering, but it doesn't seem like it'll be too bad. |
I added those in #35 in service of m4b/scroll_derive#17. I think this is another one of those design decisions that makes sense when your use cases are "structs full of primitive types" where everything is The generated |
I agree that these traits should take |
I'm working on a PR and hit this:
Context: #[repr(packed)]
struct Bar {
foo: i32,
bar: u32,
}
// …
impl scroll::ctx::IntoCtx<scroll::Endian> for Bar {
fn into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) {
use scroll::Cwrite;
bytes.cwrite_with(&self.foo, 0, ctx);
bytes.cwrite_with(&self.bar, 4, ctx);
}
} Like In this case, the impl scroll::ctx::IntoCtx<scroll::Endian> for Bar {
fn into_ctx(&self, bytes: &mut [u8], ctx: scroll::Endian) {
use scroll::Cwrite;
let Self{foo, bar} = *self;
bytes.cwrite_with(&foo, 0, ctx);
bytes.cwrite_with(&bar, 4, ctx);
}
} Backing up a bit more: how should My thoughts: we're working with bytes a field at a time, so the layout of the Rust data structure doesn't affect the binary input/output. If you're on a platform that can't do unaligned access, it seems like we'd want to handle that during the serialization step. This makes me think the Rust struct should always have optimal layout (i.e. not be |
I agree that |
Hypothesis:
#[derive(Debug,PartialEq,Hash)]
#[repr(packed)]
struct Bar {
foo: i32,
bar: u32,
}
If we're willing to require impl scroll::ctx::IntoCtx<scroll::Endian> for Bar {
fn into_ctx(&self, bytes: &mut [u8], ctx: scroll::Endian) {
use scroll::Cwrite;
bytes.cwrite_with(&{self.foo}, 0, ctx); // look ma, anonymous locals!
bytes.cwrite_with(&{self.bar}, 4, ctx);
}
} This is easy enough to handle in
I would love to produce specialized error messages for this third case, but we can't know if the field types are all |
This assumes that #[repr(packed)] types are also Copy, which is a thing we can't verify in this context. At least we're in good company: the built-in #[derive]s all require #[derive(Copy)] for packed structs. Further discussion: m4b#46 (comment)
This assumes that #[repr(packed)] types are also Copy, which is a thing we can't verify in this context. At least we're in good company: the built-in #[derive]s all require #[derive(Copy)] for packed structs. Further discussion: m4b#46 (comment)
The trait signatures are:
These traits mirror
Into
which consumesself
. However, these might be the wrong function signatures for howscroll
is used in practice; both traits are primarily used on borrowed values.scroll
implementsIntoCtx
andTryIntoCtx
on borrowed primitive types, suggesting that[Try]IntoCtx
needn't consume its value after all.scroll_derive
generates code implementingIntoCtx
andTryIntoCtx
onSelf
by borrowing and delegating to the implementation on&'a Self
.Should these traits take
&self
instead ofself
?The text was updated successfully, but these errors were encountered: