This commit is contained in:
sxyazi 2026-04-02 19:12:34 +08:00
parent 35f376abf3
commit edd9ecdc17
No known key found for this signature in database
6 changed files with 87 additions and 52 deletions

View file

@ -1,6 +1,6 @@
use serde::{Deserializer, de::{self, Error, IntoDeserializer, MapAccess, SeqAccess}}; 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 { impl<'de> Deserializer<'de> for &'de Data {
type Error = de::value::Error; 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::Id(i) => visitor.visit_u64(i.get()),
Data::Url(u) => u.into_deserializer().deserialize_any(visitor), Data::Url(u) => u.into_deserializer().deserialize_any(visitor),
Data::Path(_) => Err(Error::custom("path not supported")), 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")), Data::Any(_) => Err(Error::custom("any not supported")),
} }
} }
@ -135,7 +135,10 @@ impl<'de> Deserializer<'de> for &'de Data {
where where
V: de::Visitor<'de>, 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@ -196,7 +199,7 @@ impl<'de> Deserializer<'de> for &'de Data {
{ {
match self { match self {
Data::List(l) => visitor.visit_seq(SeqDeserializer { iter: l.iter() }), 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")), _ => Err(Error::custom("not a sequence")),
} }
} }
@ -297,24 +300,6 @@ impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
fn size_hint(&self) -> Option<usize> { Some(self.iter.len()) } fn size_hint(&self) -> Option<usize> { 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<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
self.iter.next().map(|value| seed.deserialize((*value).into_deserializer())).transpose()
}
fn size_hint(&self) -> Option<usize> { Some(self.iter.len()) }
}
// --- Map // --- Map
struct MapDeserializer<'a> { struct MapDeserializer<'a> {
iter: hashbrown::hash_map::Iter<'a, DataKey, Data>, iter: hashbrown::hash_map::Iter<'a, DataKey, Data>,

View file

@ -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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_some(self)
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
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<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
}
}

View file

@ -2,7 +2,7 @@ use std::borrow::Cow;
use serde::{Deserializer, de::{self, Error, IntoDeserializer, MapAccess, SeqAccess}}; 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 { impl<'de> Deserializer<'de> for Data {
type Error = de::value::Error; type Error = de::value::Error;
@ -23,7 +23,7 @@ impl<'de> Deserializer<'de> for Data {
Data::Id(i) => visitor.visit_u64(i.get()), Data::Id(i) => visitor.visit_u64(i.get()),
Data::Url(u) => u.into_deserializer().deserialize_any(visitor), Data::Url(u) => u.into_deserializer().deserialize_any(visitor),
Data::Path(_) => Err(Error::custom("path not supported")), 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")), Data::Any(_) => Err(Error::custom("any not supported")),
} }
} }
@ -141,7 +141,7 @@ impl<'de> Deserializer<'de> for Data {
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
match self { match self {
Data::Bytes(b) => visitor.visit_byte_buf(b), Data::Bytes(b) => BytesDeserializer(b.into()).deserialize_bytes(visitor),
_ => Err(Error::custom("not bytes")), _ => Err(Error::custom("not bytes")),
} }
} }
@ -204,7 +204,7 @@ impl<'de> Deserializer<'de> for Data {
{ {
match self { match self {
Data::List(l) => visitor.visit_seq(SeqDeserializer { iter: l.into_iter() }), 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")), _ => Err(Error::custom("not a sequence")),
} }
} }
@ -305,24 +305,6 @@ impl<'de> SeqAccess<'de> for SeqDeserializer {
fn size_hint(&self) -> Option<usize> { Some(self.iter.len()) } fn size_hint(&self) -> Option<usize> { Some(self.iter.len()) }
} }
// --- ByteSeq
struct ByteSeqDeserializer {
iter: std::vec::IntoIter<u8>,
}
impl<'de> SeqAccess<'de> for ByteSeqDeserializer {
type Error = de::value::Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
self.iter.next().map(|value| seed.deserialize(value.into_deserializer())).transpose()
}
fn size_hint(&self) -> Option<usize> { Some(self.iter.len()) }
}
// --- Map // --- Map
struct MapDeserializer { struct MapDeserializer {
iter: hashbrown::hash_map::IntoIter<DataKey, Data>, iter: hashbrown::hash_map::IntoIter<DataKey, Data>,

View file

@ -1,4 +1,4 @@
#[macro_use] #[macro_use]
mod macros; 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);

View file

@ -5,7 +5,7 @@ use serde::Deserialize;
use crate::{pool::Symbol, scheme::{AsScheme, SchemeRef}}; use crate::{pool::Symbol, scheme::{AsScheme, SchemeRef}};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)] #[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
#[serde(tag = "kind", rename_all = "lowercase")] #[serde(tag = "kind", rename_all = "kebab-case")]
pub enum Scheme { pub enum Scheme {
Regular { uri: usize, urn: usize }, Regular { uri: usize, urn: usize },
Search { domain: Symbol<str>, uri: usize, urn: usize }, Search { domain: Symbol<str>, uri: usize, urn: usize },

View file

@ -1,8 +1,8 @@
use std::borrow::Cow; 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>); 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()); return seed.deserialize(urn.into_deserializer());
} }
if let Some(path) = self.path.take() { if let Some(path) = self.path.take() {
return match path { return seed.deserialize(BytesDeserializer(path));
Cow::Borrowed(bytes) => seed.deserialize(SeqDeserializer::new(bytes.iter().copied())),
Cow::Owned(bytes) => seed.deserialize(SeqDeserializer::new(bytes.into_iter())),
};
} }
Err(de::Error::custom("value missing for key")) Err(de::Error::custom("value missing for key"))