Hello. I'm implementing Redbin format for serde. So far It went fairly well, despite I'm new to Rust. Although, for 4 days already I'm struggling with lifetimes, when trying to implement deserialization into &str
. I'd be grateful for anyone to give me any guidance.
My idea is to pass an empty Vec<u8>
to the deserializer, so that It could live after deserialization, together with slices created from the input. I cannot just return slices of input, because it has to be transcoded. Perhaps there could be a better approach?
I managed to distill a minimal example from my code, illustrating the error (please run cargo test
to see):
////////////////////////////////////////////////////////////////////////////////
/// Redbin format minimal example:
pub struct Deserializer<'de> {
input: &'de [u8],
buf: &'de mut Vec<u8>,
}
impl<'de> Deserializer<'de> {
fn parse_string(&mut self) -> Result<String> {
Ok(String::from("transcoded from Deserializer::input"))
}
}
impl<'de, 'a: 'de> DeDeserializer<'de> for &'a mut Deserializer<'de> {
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let start = self.buf.len();
let mut bytes = self.parse_string()?.into_bytes();
self.buf.append(&mut bytes);
let b: &'de [u8] = &self.buf[start..];
visitor.visit_borrowed_str(unsafe { std::str::from_utf8_unchecked(b) })
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_string(self.parse_string()?)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let value = visitor.visit_map(BlockData::new(self, 0))?;
Ok(value)
}
}
struct BlockData<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
elements: i32,
}
impl<'a, 'de> BlockData<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, len: i32) -> Self {
BlockData { de, elements: len }
}
}
impl<'de, 'a: 'de> MapAccess<'de> for BlockData<'a, 'de> {
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'de>,
{
let v = seed.deserialize(&mut *self.de)?;
Ok(v)
}
}
////////////////////////////////////////////////////////////////////////////////
/// Extracted from serde sourcecode:
pub trait DeDeserializer<'de>: Sized {
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>;
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>;
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>;
}
pub trait MapAccess<'de> {
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'de>;
}
pub trait Visitor<'de>: Sized {
type Value;
fn visit_borrowed_str(self, v: &'de str) -> Result<Self::Value> {
Err(Error::Dummy)
}
fn visit_string(self, v: String) -> Result<Self::Value> {
Err(Error::Dummy)
}
fn visit_map<A>(self, map: A) -> Result<Self::Value> {
let _ = map;
Err(Error::Dummy)
}
}
pub trait DeserializeSeed<'de>: Sized {
type Value;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value>
where
D: DeDeserializer<'de>;
}
pub trait Deserialize<'de>: Sized {
fn deserialize<D>(deserializer: D) -> Result<Self>
where
D: DeDeserializer<'de>;
}
pub type Result<T> = std::result::Result<T, Error>;
pub enum Error {
Dummy
}