Here's a version that works.
Playground
I changed two things. The first thing I changed was the function signature on get_slice
and parse_bytes
from
fn get_slice(&'de self, len: usize) -> Result<&'de [u8]>
fn parse_bytes(&'de self) -> Result<&'de [u8]>
to
fn get_slice(&self, len: usize) -> Result<&'de [u8]>
fn parse_bytes(&self) -> Result<&'de [u8]>
Notice that I removed the 'de
lifetime specifier on self
. That is overly restrictive since it is saying that in order to use those functions the borrow of self
must be for the exact same lifetime as the data inside of self (usually you want to allow for the outer borrow to be shorter than the inner one). To illustrate that a bit better expanded version of those function signatures would be
fn get_slice(self: &'de Deserializer<'de>, len: usize) -> Result<&'de [u8]>
and my change effectively made it
fn get_slice<'a>(self: &'a Deserializer<'de>, len: usize) -> Result<&'de [u8]>
Looking at it this way, the new version allows for the borrow of the Deserializer
(what I've given lifetime 'a
) to be for shorter than the borrow of the underlying data 'de
The second change, which may or may not work for you, is i changed the struct definition from
pub struct Deserializer<'de> {
input: &'de mut [u8],
cursor_: usize,
cursor: *mut usize,
len: u8,
}
to
pub struct Deserializer<'de> {
input: &'de [u8],
cursor_: usize,
cursor: *mut usize,
len: u8,
}
This has to do with borrowing rules as to why this is needed. Without the change, the compiler complains about lifetimes for the get_slice
definition. Specifically it complains about
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:76:20
|
76 | let res = &self.input[cursor..=cursor + l];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 64:5...
--> src/main.rs:64:5
|
64 | fn get_slice(&self, len: usize) -> Result<&'de [u8]> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:76:20
|
76 | let res = &self.input[cursor..=cursor + l];
| ^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'de` as defined on the impl at 63:6...
--> src/main.rs:63:6
|
63 | impl<'de> Deserializer<'de> {
| ^^^
note: ...so that the expression is assignable
--> src/main.rs:77:9
|
77 | Ok(res)
| ^^^^^^^
= note: expected `std::result::Result<&'de [u8], _>`
found `std::result::Result<&[u8], _>`
The primary issue here is that the lifetime of res
is not 'de
. This comes out of the fact that since self
has mutable access to input
, you can't reborrow (which is what you're doing) with the same lifetime as the lifetime of the mutable borrow. (I always forget the technical reason for this, but someone may come in with the correct info for that). And the reason I thought it was fine to change it was that it didn't seem like you actually needed mut
access to the data since you probably don't want to make any changes to the data anyway.
All that said, this code is not exactly idiomatic Rust. I took a quick pass at it and came up with this. The basic changes were to get rid of the pointer type which you don't really need and it introduces unsafe code into rust which I try to avoid completely. The other thing it changes is that instead of holding a reference to the entire original slice of data, it only stores the remaining data in the struct which simplifies things (and also in theory would allow you to add back in the mut
into the struct definition if thats needed for some reason). In theory, you also probably don't want len
in the struct and instead make a new custom struct to hold that len
, but I'll leave that as an exercise for you if you want to try that. (I believe there's an example of that in the serde_json
code).
Edit: Fixed last link