-
Notifications
You must be signed in to change notification settings - Fork 304
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
Is there a way to fully replace &'l [u8]
with &'l mut dyn Buf
?
#395
Comments
Here is a proposition of use bytes; // 0.5.4
use bytes::*;
trait OwnedBuf<'a>: Buf {
fn owned_bytes(&'a self) -> &'a [u8];
}
impl<'a> OwnedBuf<'a> for &'a [u8] {
fn owned_bytes(&'a self) -> &'a [u8] {
self
}
}
#[derive(Debug)]
struct Frame<'p> {
x: u8,
payload: &'p [u8],
}
impl<'p> Frame<'p> {
fn decode<'a: 'p>(buf: &'a mut dyn OwnedBuf<'a>) -> Self {
let x = buf.get_u8();
Self {
x,
payload: buf.owned_bytes()
}
}
}
fn main() {
let x = [0u8; 3];
let mut y = &x[..];
let f = Frame::decode(&mut y);
println!("{:?}", f);
} |
I used something like this, but with
impl
Here is an abbreviation of my use case that should demonstrate the flexibility. Essentially being able to take some input and store references to it in the output, and being able to nest such functions.
I hadn't gotten far enough to be confident enough to propose it, and I don't know what the pros/cons of adding this to |
For the record, the original playground can be modified to compile like this: impl<'p> Frame<'p> {
fn decode(buf: &'p mut dyn Buf) -> Self {
let x = buf.get_u8();
Self {
x,
payload: (&*buf).bytes(),
}
}
} The issue is that |
@Darksonn
Do you have any idea how to workaround also this? Here is probably what I am looking for pub trait BorrowedBuf<'a>: Buf {
fn advance_borrow(&'a mut self, cnt: usize) -> &'a [u8];
}
impl<'a> BorrowedBuf<'a> for &'a [u8] {
fn advance_borrow(&'a mut self, cnt: usize) -> &'a [u8] {
let to_ret = &self[..cnt];
*self = &self[..cnt];
to_ret
}
}
/// This should be implemented inside bytes to work.
impl<'a> BorrowedBuf<'a> for Bytes {
fn advance_borrow(&'a mut self, cnt: usize) -> &'a [u8] {
let to_ret = &self.bytes()[..cnt];
self.advance(cnt);
to_ret
}
} |
Does the usual let remaining = self.remaining();
buf.advance(remaining); trick not apply here for some reason? |
@Ralith impl<'p> Frame<'p> {
fn decode(buf: &'p mut dyn Buf) -> Self {
let x = buf.get_u8();
let r = Self {
x,
payload: (&*buf).bytes(),
};
buf.advance(buf.remaining());
r
}
} |
Ah, I see. I think what you want is reasonable, and is basically a more generic version of |
The issue here is that you can't do what you are trying to do with every implementor of
There's no guarantee that older bytes remain available as you advance the iterator. Sure, it works with A |
Yes I know that. This is why I proposed additional trait that allow you to do this. As far as I understand it |
I was trying to replace
&'a [u8]
with&'a mut dyn Buf
but I fail with lifetime problem(Playground)
As far as I understand - the lifetime returned by
buf.bytes()
should be equal to'a
defined onBuf
and should be valid at least as long as'p
. (buf
takes&'a self
as a reference).I think about
Buf
as a view or coursor over bytes. But as long as this view is valid data will be not moved. It's work when I implement similar tobytes()
method directlyWhy I don't call
to_bytes()
? this decode function isno_std
and I want give an end user full control of allocation.The text was updated successfully, but these errors were encountered: