Skip to content

Commit

Permalink
Deserialization for VarZeroVec<VarZeroSlice>, take 2 (#3649)
Browse files Browse the repository at this point in the history
* Revert "Support Deserialization for `VarZeroVec<VarZeroSlice>` (#3643)"

This reverts commit b2a1b79.

* More succinct deserialize impl for Box<VZS>
  • Loading branch information
Manishearth committed Jul 10, 2023
1 parent be4c45f commit 7465509
Showing 1 changed file with 18 additions and 98 deletions.
116 changes: 18 additions & 98 deletions utils/zerovec/src/varzerovec/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,6 @@ impl<T: ?Sized, F: VarZeroVecFormat> Default for VarZeroVecVisitor<T, F> {
}
}

struct VarZeroSliceBoxVisitor<T: ?Sized, F: VarZeroVecFormat> {
#[allow(clippy::type_complexity)] // this is a private marker type, who cares
marker: PhantomData<(fn() -> Box<T>, F)>,
}

impl<T: ?Sized, F: VarZeroVecFormat> Default for VarZeroSliceBoxVisitor<T, F> {
fn default() -> Self {
Self {
marker: PhantomData,
}
}
}

struct VarZeroSliceRefVisitor<T: ?Sized, F: VarZeroVecFormat> {
#[allow(clippy::type_complexity)] // this is a private marker type, who cares
marker: PhantomData<(fn() -> Box<T>, F)>,
}

impl<T: ?Sized, F: VarZeroVecFormat> Default for VarZeroSliceRefVisitor<T, F> {
fn default() -> Self {
Self {
marker: PhantomData,
}
}
}

impl<'de, T, F> Visitor<'de> for VarZeroVecVisitor<T, F>
where
T: VarULE + ?Sized,
Expand Down Expand Up @@ -86,62 +60,6 @@ where
}
}

impl<'de, T, F> Visitor<'de> for VarZeroSliceBoxVisitor<T, F>
where
T: VarULE + ?Sized,
Box<T>: Deserialize<'de>,
F: VarZeroVecFormat,
{
type Value = Box<VarZeroSlice<T, F>>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence or borrowed buffer of bytes")
}

fn visit_borrowed_bytes<E>(self, bytes: &'de [u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
VarZeroSlice::parse_byte_slice(bytes)
.map(VarULE::to_boxed)
.map_err(de::Error::custom)
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut vec: Vec<Box<T>> = if let Some(capacity) = seq.size_hint() {
Vec::with_capacity(capacity)
} else {
Vec::new()
};
while let Some(value) = seq.next_element::<Box<T>>()? {
vec.push(value);
}
Ok(VarZeroVec::from(&vec).to_boxed())
}
}

impl<'de, T, F> Visitor<'de> for VarZeroSliceRefVisitor<T, F>
where
T: VarULE + ?Sized,
F: VarZeroVecFormat,
{
type Value = &'de VarZeroSlice<T, F>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence or borrowed buffer of bytes")
}

fn visit_borrowed_bytes<E>(self, bytes: &'de [u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
VarZeroSlice::parse_byte_slice(bytes).map_err(de::Error::custom)
}
}

/// This impl requires enabling the optional `serde` Cargo feature of the `zerovec` crate
impl<'de, 'a, T, F> Deserialize<'de> for VarZeroVec<'a, T, F>
where
Expand All @@ -154,7 +72,7 @@ where
where
D: Deserializer<'de>,
{
let visitor: VarZeroVecVisitor<T, F> = VarZeroVecVisitor::default();
let visitor = VarZeroVecVisitor::<T, F>::default();
if deserializer.is_human_readable() {
deserializer.deserialize_seq(visitor)
} else {
Expand All @@ -167,6 +85,7 @@ where
impl<'de, 'a, T, F> Deserialize<'de> for &'a VarZeroSlice<T, F>
where
T: VarULE + ?Sized,
Box<T>: Deserialize<'de>,
F: VarZeroVecFormat,
'de: 'a,
{
Expand All @@ -179,31 +98,32 @@ where
"&VarZeroSlice cannot be deserialized from human-readable formats",
))
} else {
let visitor: VarZeroSliceRefVisitor<T, F> = VarZeroSliceRefVisitor::default();
let deserialized: &'a VarZeroSlice<_, _> = deserializer.deserialize_bytes(visitor)?;
Ok(deserialized)
let deserialized = VarZeroVec::<'a, T, F>::deserialize(deserializer)?;
let borrowed = if let VarZeroVec::Borrowed(b) = deserialized {
b
} else {
return Err(de::Error::custom(
"&VarZeroSlice can only deserialize in zero-copy ways",
));
};
Ok(borrowed)
}
}
}

/// This impl requires enabling the optional `serde` Cargo feature of the `zerovec` crate
impl<'de, 'a, T, F> Deserialize<'de> for Box<VarZeroSlice<T, F>>
impl<'de, T, F> Deserialize<'de> for Box<VarZeroSlice<T, F>>
where
T: VarULE + ?Sized,
Box<T>: Deserialize<'de>,
F: VarZeroVecFormat,
'de: 'a,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let visitor: VarZeroSliceBoxVisitor<T, F> = VarZeroSliceBoxVisitor::default();
if deserializer.is_human_readable() {
deserializer.deserialize_seq(visitor)
} else {
deserializer.deserialize_bytes(visitor)
}
let deserialized = VarZeroVec::<T, F>::deserialize(deserializer)?;
Ok(deserialized.to_boxed())
}
}

Expand Down Expand Up @@ -257,15 +177,15 @@ mod test {
}

#[derive(serde::Serialize, serde::Deserialize)]
struct DeriveTest_VarZeroVec_of_VarZeroSlice<'data> {
struct DeriveTest_VarZeroSlice<'data> {
#[serde(borrow)]
_data: VarZeroVec<'data, VarZeroSlice<str>>,
_data: &'data VarZeroSlice<str>,
}

#[derive(serde::Serialize, serde::Deserialize)]
struct DeriveTest_VarZeroSlice<'data> {
struct DeriveTest_VarZeroVec_of_VarZeroSlice<'data> {
#[serde(borrow)]
_data: &'data VarZeroSlice<str>,
_data: VarZeroVec<'data, VarZeroSlice<str>>,
}

// ["foo", "bar", "baz", "dolor", "quux", "lorem ipsum"];
Expand Down

0 comments on commit 7465509

Please sign in to comment.