mirror of
https://github.com/openharmony/third_party_rust_tinyvec.git
synced 2026-07-19 14:23:33 -04:00
Add Serde support (#110)
* Add Serde support. * Removes `serde/alloc` from deps( tests still pass without it anyways) * Fix some issues that could result in a panic. * Wait, actually use the size_hint properly. * Error instead of silent truncation. * That wasn't meant to be a default feature.
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
use super::*;
|
||||
use core::convert::TryInto;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use core::marker::PhantomData;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::de::{
|
||||
Deserialize, Deserializer, Error as DeserializeError, SeqAccess, Visitor,
|
||||
};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::ser::{Serialize, SerializeSeq, Serializer};
|
||||
|
||||
/// Helper to make an `ArrayVec`.
|
||||
///
|
||||
/// You specify the backing array type, and optionally give all the elements you
|
||||
@@ -130,6 +139,38 @@ impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for ArrayVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<A: Array> Serialize for ArrayVec<A>
|
||||
where
|
||||
A::Item: Serialize,
|
||||
{
|
||||
#[must_use]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(self.len()))?;
|
||||
for element in self.iter() {
|
||||
seq.serialize_element(element)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Deserialize<'de> for ArrayVec<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_seq(ArrayVecVisitor(PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Array> ArrayVec<A> {
|
||||
/// Move all values from `other` into this vec.
|
||||
///
|
||||
@@ -1502,3 +1543,40 @@ impl<A: Array> ArrayVec<A> {
|
||||
self.drain_to_vec_and_reserve(0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
struct ArrayVecVisitor<A: Array>(PhantomData<A>);
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Visitor<'de> for ArrayVecVisitor<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
type Value = ArrayVec<A>;
|
||||
|
||||
fn expecting(
|
||||
&self,
|
||||
formatter: &mut core::fmt::Formatter,
|
||||
) -> core::fmt::Result {
|
||||
formatter.write_str("a sequence")
|
||||
}
|
||||
|
||||
fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
|
||||
where
|
||||
S: SeqAccess<'de>,
|
||||
{
|
||||
let mut new_arrayvec: ArrayVec<A> = Default::default();
|
||||
|
||||
let mut idx = 0usize;
|
||||
while let Some(value) = seq.next_element()? {
|
||||
if new_arrayvec.len() >= new_arrayvec.capacity() {
|
||||
return Err(DeserializeError::invalid_length(idx, &self));
|
||||
}
|
||||
new_arrayvec.push(value);
|
||||
idx = idx + 1;
|
||||
}
|
||||
|
||||
Ok(new_arrayvec)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
//! ArrayVec.
|
||||
//! * `rustc_1_40` makes the crate assume a minimum rust version of `1.40.0`,
|
||||
//! which allows some better internal optimizations.
|
||||
//! * `serde` provides a `Serialize` and `Deserialize` implementation for
|
||||
//! [`TinyVec`] and [`ArrayVec`] types, provided the inner item also
|
||||
//! has an implementation.
|
||||
//!
|
||||
//! ## API
|
||||
//! The general goal of the crate is that, as much as possible, the vecs here
|
||||
|
||||
@@ -5,6 +5,13 @@ use super::*;
|
||||
use alloc::vec::{self, Vec};
|
||||
use tinyvec_macros::impl_mirrored;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use core::marker::PhantomData;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::ser::{Serialize, SerializeSeq, Serializer};
|
||||
|
||||
/// Helper to make a `TinyVec`.
|
||||
///
|
||||
/// You specify the backing array type, and optionally give all the elements you
|
||||
@@ -136,6 +143,38 @@ impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<A: Array> Serialize for TinyVec<A>
|
||||
where
|
||||
A::Item: Serialize,
|
||||
{
|
||||
#[must_use]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(self.len()))?;
|
||||
for element in self.iter() {
|
||||
seq.serialize_element(element)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Deserialize<'de> for TinyVec<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_seq(TinyVecVisitor(PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Array> TinyVec<A> {
|
||||
/// Returns whether elements are on heap
|
||||
#[inline(always)]
|
||||
@@ -1411,3 +1450,38 @@ where
|
||||
write!(f, "]")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
struct TinyVecVisitor<A: Array>(PhantomData<A>);
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, A: Array> Visitor<'de> for TinyVecVisitor<A>
|
||||
where
|
||||
A: Default,
|
||||
A::Item: Deserialize<'de>,
|
||||
{
|
||||
type Value = TinyVec<A>;
|
||||
|
||||
fn expecting(
|
||||
&self,
|
||||
formatter: &mut core::fmt::Formatter,
|
||||
) -> core::fmt::Result {
|
||||
formatter.write_str("a sequence")
|
||||
}
|
||||
|
||||
fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
|
||||
where
|
||||
S: SeqAccess<'de>,
|
||||
{
|
||||
let mut new_tinyvec = match seq.size_hint() {
|
||||
Some(expected_size) => TinyVec::with_capacity(expected_size),
|
||||
None => Default::default(),
|
||||
};
|
||||
|
||||
while let Some(value) = seq.next_element()? {
|
||||
new_tinyvec.push(value);
|
||||
}
|
||||
|
||||
Ok(new_tinyvec)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user