diff --git a/yazi-shared/src/data/de.rs b/yazi-shared/src/data/de.rs index f09722a1..2f988354 100644 --- a/yazi-shared/src/data/de.rs +++ b/yazi-shared/src/data/de.rs @@ -1,6 +1,6 @@ use serde::{Deserializer, de::{self, Error, IntoDeserializer, MapAccess, SeqAccess}}; -use crate::data::{Data, DataKey, KeyDeserializer}; +use crate::data::{BytesDeserializer, Data, DataKey, KeyDeserializer}; impl<'de> Deserializer<'de> for &'de Data { type Error = de::value::Error; @@ -20,7 +20,7 @@ impl<'de> Deserializer<'de> for &'de Data { Data::Id(i) => visitor.visit_u64(i.get()), Data::Url(u) => u.into_deserializer().deserialize_any(visitor), Data::Path(_) => Err(Error::custom("path not supported")), - Data::Bytes(b) => visitor.visit_borrowed_bytes(b), + Data::Bytes(b) => BytesDeserializer(b.into()).deserialize_any(visitor), Data::Any(_) => Err(Error::custom("any not supported")), } } @@ -135,7 +135,10 @@ impl<'de> Deserializer<'de> for &'de Data { where V: de::Visitor<'de>, { - visitor.visit_bytes(self.try_into().map_err(Error::custom)?) + match self { + Data::Bytes(b) => BytesDeserializer(b.into()).deserialize_bytes(visitor), + _ => Err(Error::custom("not bytes")), + } } fn deserialize_byte_buf(self, visitor: V) -> Result @@ -196,7 +199,7 @@ impl<'de> Deserializer<'de> for &'de Data { { match self { Data::List(l) => visitor.visit_seq(SeqDeserializer { iter: l.iter() }), - Data::Bytes(b) => visitor.visit_seq(ByteSeqDeserializer { iter: b.iter() }), + Data::Bytes(b) => BytesDeserializer(b.into()).deserialize_seq(visitor), _ => Err(Error::custom("not a sequence")), } } @@ -297,24 +300,6 @@ impl<'de> SeqAccess<'de> for SeqDeserializer<'de> { fn size_hint(&self) -> Option { Some(self.iter.len()) } } -// --- ByteSeq -struct ByteSeqDeserializer<'a> { - iter: std::slice::Iter<'a, u8>, -} - -impl<'de> SeqAccess<'de> for ByteSeqDeserializer<'de> { - type Error = de::value::Error; - - fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> - where - T: de::DeserializeSeed<'de>, - { - self.iter.next().map(|value| seed.deserialize((*value).into_deserializer())).transpose() - } - - fn size_hint(&self) -> Option { Some(self.iter.len()) } -} - // --- Map struct MapDeserializer<'a> { iter: hashbrown::hash_map::Iter<'a, DataKey, Data>, diff --git a/yazi-shared/src/data/de_bytes.rs b/yazi-shared/src/data/de_bytes.rs new file mode 100644 index 00000000..3dcee3c4 --- /dev/null +++ b/yazi-shared/src/data/de_bytes.rs @@ -0,0 +1,71 @@ +use std::borrow::Cow; + +use serde::{Deserializer, de::{self, value::SeqDeserializer}}; + +pub(crate) struct BytesDeserializer<'a>(pub(crate) Cow<'a, [u8]>); + +impl<'de, 'a: 'de> Deserializer<'de> for BytesDeserializer<'a> { + type Error = de::value::Error; + + serde::forward_to_deserialize_any! { + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string unit unit_struct + map struct enum bytes byte_buf identifier ignored_any + } + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.0 { + Cow::Borrowed(b) => visitor.visit_borrowed_bytes(b), + Cow::Owned(b) => visitor.visit_byte_buf(b), + } + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_some(self) + } + + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.0 { + Cow::Borrowed(b) => visitor.visit_seq(SeqDeserializer::new(b.iter().copied())), + Cow::Owned(b) => visitor.visit_seq(SeqDeserializer::new(b.into_iter())), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } +} diff --git a/yazi-shared/src/data/de_owned.rs b/yazi-shared/src/data/de_owned.rs index 3db42d52..863c1150 100644 --- a/yazi-shared/src/data/de_owned.rs +++ b/yazi-shared/src/data/de_owned.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use serde::{Deserializer, de::{self, Error, IntoDeserializer, MapAccess, SeqAccess}}; -use crate::data::{Data, DataKey, KeyDeserializer}; +use crate::data::{BytesDeserializer, Data, DataKey, KeyDeserializer}; impl<'de> Deserializer<'de> for Data { type Error = de::value::Error; @@ -23,7 +23,7 @@ impl<'de> Deserializer<'de> for Data { Data::Id(i) => visitor.visit_u64(i.get()), Data::Url(u) => u.into_deserializer().deserialize_any(visitor), Data::Path(_) => Err(Error::custom("path not supported")), - Data::Bytes(b) => visitor.visit_byte_buf(b), + Data::Bytes(b) => BytesDeserializer(b.into()).deserialize_any(visitor), Data::Any(_) => Err(Error::custom("any not supported")), } } @@ -141,7 +141,7 @@ impl<'de> Deserializer<'de> for Data { V: de::Visitor<'de>, { match self { - Data::Bytes(b) => visitor.visit_byte_buf(b), + Data::Bytes(b) => BytesDeserializer(b.into()).deserialize_bytes(visitor), _ => Err(Error::custom("not bytes")), } } @@ -204,7 +204,7 @@ impl<'de> Deserializer<'de> for Data { { match self { Data::List(l) => visitor.visit_seq(SeqDeserializer { iter: l.into_iter() }), - Data::Bytes(b) => visitor.visit_seq(ByteSeqDeserializer { iter: b.into_iter() }), + Data::Bytes(b) => BytesDeserializer(b.into()).deserialize_seq(visitor), _ => Err(Error::custom("not a sequence")), } } @@ -305,24 +305,6 @@ impl<'de> SeqAccess<'de> for SeqDeserializer { fn size_hint(&self) -> Option { Some(self.iter.len()) } } -// --- ByteSeq -struct ByteSeqDeserializer { - iter: std::vec::IntoIter, -} - -impl<'de> SeqAccess<'de> for ByteSeqDeserializer { - type Error = de::value::Error; - - fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> - where - T: de::DeserializeSeed<'de>, - { - self.iter.next().map(|value| seed.deserialize(value.into_deserializer())).transpose() - } - - fn size_hint(&self) -> Option { Some(self.iter.len()) } -} - // --- Map struct MapDeserializer { iter: hashbrown::hash_map::IntoIter, diff --git a/yazi-shared/src/data/mod.rs b/yazi-shared/src/data/mod.rs index 25b21b53..1f290c8a 100644 --- a/yazi-shared/src/data/mod.rs +++ b/yazi-shared/src/data/mod.rs @@ -1,4 +1,4 @@ #[macro_use] mod macros; -yazi_macro::mod_flat!(any data de de_key de_owned key); +yazi_macro::mod_flat!(any data de de_bytes de_key de_owned key); diff --git a/yazi-shared/src/scheme/scheme.rs b/yazi-shared/src/scheme/scheme.rs index 6a086b1f..8148a431 100644 --- a/yazi-shared/src/scheme/scheme.rs +++ b/yazi-shared/src/scheme/scheme.rs @@ -5,7 +5,7 @@ use serde::Deserialize; use crate::{pool::Symbol, scheme::{AsScheme, SchemeRef}}; #[derive(Clone, Debug, Deserialize, Eq, PartialEq)] -#[serde(tag = "kind", rename_all = "lowercase")] +#[serde(tag = "kind", rename_all = "kebab-case")] pub enum Scheme { Regular { uri: usize, urn: usize }, Search { domain: Symbol, uri: usize, urn: usize }, diff --git a/yazi-shared/src/url/de.rs b/yazi-shared/src/url/de.rs index 341288b7..306b0f0d 100644 --- a/yazi-shared/src/url/de.rs +++ b/yazi-shared/src/url/de.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; -use serde::{Deserializer, de::{self, IntoDeserializer, MapAccess, value::SeqDeserializer}}; +use serde::{Deserializer, de::{self, IntoDeserializer, MapAccess}}; -use crate::{pool::SymbolCow, scheme::SchemeLike, url::UrlCow}; +use crate::{data::BytesDeserializer, pool::SymbolCow, scheme::SchemeLike, url::UrlCow}; pub struct UrlDeserializer<'a>(pub(super) UrlCow<'a>); @@ -95,10 +95,7 @@ impl<'de, 'a: 'de> MapAccess<'de> for MapDeserializer<'a> { return seed.deserialize(urn.into_deserializer()); } if let Some(path) = self.path.take() { - return match path { - Cow::Borrowed(bytes) => seed.deserialize(SeqDeserializer::new(bytes.iter().copied())), - Cow::Owned(bytes) => seed.deserialize(SeqDeserializer::new(bytes.into_iter())), - }; + return seed.deserialize(BytesDeserializer(path)); } Err(de::Error::custom("value missing for key"))