summaryrefslogtreecommitdiff
path: root/vendor/fixedbitset/src/serde_impl.rs
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
committermo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
commit8cdfa445d6629ffef4cb84967ff7017654045bc2 (patch)
tree22f0b0907c024c78d26a731e2e1f5219407d8102 /vendor/fixedbitset/src/serde_impl.rs
parent4351c74c7c5f97156bc94d3a8549b9940ac80e3f (diff)
chore: add vendor directory
Diffstat (limited to 'vendor/fixedbitset/src/serde_impl.rs')
-rw-r--r--vendor/fixedbitset/src/serde_impl.rs150
1 files changed, 150 insertions, 0 deletions
diff --git a/vendor/fixedbitset/src/serde_impl.rs b/vendor/fixedbitset/src/serde_impl.rs
new file mode 100644
index 00000000..98231599
--- /dev/null
+++ b/vendor/fixedbitset/src/serde_impl.rs
@@ -0,0 +1,150 @@
+#[cfg(not(feature = "std"))]
+use core as std;
+
+use crate::{Block, FixedBitSet, BYTES};
+use alloc::vec::Vec;
+use core::{convert::TryFrom, fmt};
+use serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
+use serde::ser::{Serialize, SerializeStruct, Serializer};
+
+struct BitSetByteSerializer<'a>(&'a FixedBitSet);
+
+impl Serialize for FixedBitSet {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut struct_serializer = serializer.serialize_struct("FixedBitset", 2)?;
+ struct_serializer.serialize_field("length", &(self.length as u64))?;
+ struct_serializer.serialize_field("data", &BitSetByteSerializer(self))?;
+ struct_serializer.end()
+ }
+}
+
+impl<'a> Serialize for BitSetByteSerializer<'a> {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let len = self.0.as_slice().len() * BYTES;
+ // PERF: Figure out a way to do this without allocating.
+ let mut temp = Vec::with_capacity(len);
+ for block in self.0.as_slice() {
+ temp.extend(&block.to_le_bytes());
+ }
+ serializer.serialize_bytes(&temp)
+ }
+}
+
+impl<'de> Deserialize<'de> for FixedBitSet {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ enum Field {
+ Length,
+ Data,
+ }
+
+ fn bytes_to_data(length: usize, input: &[u8]) -> Vec<Block> {
+ let block_len = length / BYTES + 1;
+ let mut data = Vec::with_capacity(block_len);
+ for chunk in input.chunks(BYTES) {
+ match <&[u8; BYTES]>::try_from(chunk) {
+ Ok(bytes) => data.push(usize::from_le_bytes(*bytes)),
+ Err(_) => {
+ let mut bytes = [0u8; BYTES];
+ bytes[0..BYTES].copy_from_slice(chunk);
+ data.push(usize::from_le_bytes(bytes));
+ }
+ }
+ }
+ data
+ }
+
+ impl<'de> Deserialize<'de> for Field {
+ fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct FieldVisitor;
+
+ impl<'de> Visitor<'de> for FieldVisitor {
+ type Value = Field;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("`length` or `data`")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Field, E>
+ where
+ E: de::Error,
+ {
+ match value {
+ "length" => Ok(Field::Length),
+ "data" => Ok(Field::Data),
+ _ => Err(de::Error::unknown_field(value, FIELDS)),
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)
+ }
+ }
+
+ struct FixedBitSetVisitor;
+
+ impl<'de> Visitor<'de> for FixedBitSetVisitor {
+ type Value = FixedBitSet;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("struct Duration")
+ }
+
+ fn visit_seq<V>(self, mut seq: V) -> Result<FixedBitSet, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ let length = seq
+ .next_element()?
+ .ok_or_else(|| de::Error::invalid_length(0, &self))?;
+ let data: &[u8] = seq
+ .next_element()?
+ .ok_or_else(|| de::Error::invalid_length(1, &self))?;
+ let data = bytes_to_data(length, data);
+ Ok(FixedBitSet::with_capacity_and_blocks(length, data))
+ }
+
+ fn visit_map<V>(self, mut map: V) -> Result<FixedBitSet, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ let mut length = None;
+ let mut temp: Option<&[u8]> = None;
+ while let Some(key) = map.next_key()? {
+ match key {
+ Field::Length => {
+ if length.is_some() {
+ return Err(de::Error::duplicate_field("length"));
+ }
+ length = Some(map.next_value()?);
+ }
+ Field::Data => {
+ if temp.is_some() {
+ return Err(de::Error::duplicate_field("data"));
+ }
+ temp = Some(map.next_value()?);
+ }
+ }
+ }
+ let length = length.ok_or_else(|| de::Error::missing_field("length"))?;
+ let data = temp.ok_or_else(|| de::Error::missing_field("data"))?;
+ let data = bytes_to_data(length, data);
+ Ok(FixedBitSet::with_capacity_and_blocks(length, data))
+ }
+ }
+
+ const FIELDS: &'static [&'static str] = &["length", "data"];
+ deserializer.deserialize_struct("Duration", FIELDS, FixedBitSetVisitor)
+ }
+}