// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright 2020, Alyssa Ross
//
// Portions Copyright Erick Tryzelaar and David Tolnay.
// Licensed under either of Apache License, Version 2.0
// or MIT license at your option.
//! Data structure deserialization framework for Unix domain sockets.
//!
//! Much like `serde::de`, except receiving file descriptors is also
//! supported.
use crate::Fd;
use std::cmp::min;
use std::collections::BTreeMap;
use std::fmt::{self, Formatter};
use std::marker::PhantomData;
pub use serde::de::{
Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, StdError,
VariantAccess, Visitor,
};
/// A generic container for an inner serde type, and some file descriptors.
///
/// Useful for implementing assorted `*WithFds` traits in terms of
/// their serde equivalents.
#[derive(Debug)]
pub(crate) struct WithFds<'fds, T, F> {
pub inner: T,
pub fds: &'fds mut F,
}
/// Like `Deserialize`, but provides file descriptors as well as data.
pub trait DeserializeWithFds<'de>: Sized {
/// Like `Deserialize::deserialize`, but `deserializer` is a
/// `DeserializerWithFds` instead of a `Deserializer`.
fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error>;
}
/// Like `DeserializeSeed`, but provides file descriptors as well as
/// data.
pub trait DeserializeWithFdsSeed<'de>: Sized {
/// Like `DeserializeSeed::Value`.
type Value;
/// Like `DeserializeSeed::deserialize`, but `deserializer` is a
/// `DeserializerWithFds` instead of a `Deserializer`.
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: DeserializerWithFds<'de>;
}
impl<'de, T: DeserializeWithFds<'de>> DeserializeWithFdsSeed<'de> for PhantomData<T> {
type Value = T;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: DeserializerWithFds<'de>,
{
T::deserialize(deserializer)
}
}
impl<'fds, 'de, T, F> DeserializeSeed<'de> for WithFds<'fds, T, F>
where
F: Iterator<Item = Fd>,
T: DeserializeWithFdsSeed<'de>,
{
type Value = T::Value;
fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
let deserializer_with_fds = WithFds {
inner: deserializer,
fds: self.fds,
};
self.inner.deserialize(deserializer_with_fds)
}
}
/// Like `Deserializer` but provides file descriptors as well as data.
pub trait DeserializerWithFds<'de> {
/// Like `Deserializer::Error`.
type Error: Error;
/// Deserialize a file descriptor.
fn deserialize_fd(self) -> Result<Fd, Self::Error>;
/// Like `Deserializer::deserialize_option`, but `visitor` is a
/// `VisitorWithFds` instead of a `Visitor`.
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: VisitorWithFds<'de>;
/// Like `Deserializer::deserialize_seq` but `visitor` is a
/// `VisitorWithFds` instead of a `Visitor`.
fn deserialize_seq<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
/// Like `Deserializer::deserialize_tuple_struct`, but `visitor`
/// is a `VisitorWithFds` instead of a `Visitor`.
fn deserialize_tuple_struct<V: VisitorWithFds<'de>>(
self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>;
/// Like `Deserializer::deserialize_map` but `visitor` is a
/// `VisitorWithFds` instead of a `Visitor`.
fn deserialize_map<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
/// Like `Deserializer::deserialize_struct` but `visitor` is a
/// `VisitorWithFds` instead of a `Visitor`.
fn deserialize_struct<V: VisitorWithFds<'de>>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>;
/// Like `Deserializer::deserialize_enum` but `visitor` is a
/// `VisitorWithFds` instead of a `Visitor`.
fn deserialize_enum<V: VisitorWithFds<'de>>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>;
/// Invite a `Visitor` to visit a `Some` value.
///
/// The purpose of this indirection is to allow implementations to
/// control how `Visitor::visit_some` is called. This means that
/// whatever way they get a `Deserializer` to pass to it doesn't
/// have to be exposed publicly through the trait.
///
/// This looks a lot like a `deserialize_*` method, but it takes a
/// `Visitor` instead of a `VisitorWithFds`, and it's not part of
/// the serde interface.
fn invite_visit_some<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
/// Invite a `Deserialize` to deserialize.
///
/// The purpose of this indirection is to allow implementations to
/// control how `Deserialize::deserialize` is called. This means
/// that whatever way they get a `Deserializer` to pass to it
/// doesn't have to be exposed publicly through the trait.
fn invite_deserialize<T: Deserialize<'de>>(self) -> Result<T, Self::Error>;
}
impl<'fds, 'de, D, F> DeserializerWithFds<'de> for WithFds<'fds, D, F>
where
D: Deserializer<'de>,
F: Iterator<Item = Fd>,
{
type Error = D::Error;
fn deserialize_fd(self) -> Result<Fd, Self::Error> {
struct UnitVisitor;
impl<'de> Visitor<'de> for UnitVisitor {
type Value = ();
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "expecting unit")
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(())
}
}
// This is probably not necessary, since unit should be
// serialized to nothing, but it's more correct to do this,
// because unit was serialized, and so unit should be
// deserialized.
self.inner.deserialize_unit(UnitVisitor)?;
self.fds
.next()
.ok_or_else(|| Self::Error::custom("no fds to deserialize"))
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: VisitorWithFds<'de>,
{
let wrapper = WithFds {
inner: visitor,
fds: self.fds,
};
self.inner.deserialize_option(wrapper)
}
fn deserialize_seq<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, D::Error> {
let wrapper = WithFds {
inner: visitor,
fds: self.fds,
};
self.inner.deserialize_seq(wrapper)
}
fn deserialize_tuple_struct<V: VisitorWithFds<'de>>(
self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value, Self::Error> {
let wrapper = WithFds {
inner: visitor,
fds: self.fds,
};
self.inner.deserialize_tuple_struct(name, len, wrapper)
}
fn deserialize_map<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, D::Error> {
let wrapper = WithFds {
inner: visitor,
fds: self.fds,
};
self.inner.deserialize_map(wrapper)
}
fn deserialize_struct<V: VisitorWithFds<'de>>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, D::Error> {
let wrapper = WithFds {
inner: visitor,
fds: self.fds,
};
self.inner.deserialize_struct(name, fields, wrapper)
}
fn deserialize_enum<V: VisitorWithFds<'de>>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, D::Error> {
let wrapper = WithFds {
inner: visitor,
fds: self.fds,
};
self.inner.deserialize_enum(name, variants, wrapper)
}
fn invite_visit_some<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, D::Error> {
visitor.visit_some(self.inner)
}
fn invite_deserialize<T: Deserialize<'de>>(self) -> Result<T, D::Error> {
T::deserialize(self.inner)
}
}
/// A type implementing `Visitor` without any overrides.
///
/// This allows for referring to the default serde implementation of
/// the `Visitor` methods from our own overrides.
#[derive(Debug)]
struct VisitorDefaults<'a, V>(PhantomData<&'a V>);
impl<'a, 'de, V> Visitor<'de> for VisitorDefaults<'a, V> {
type Value = V;
fn expecting(&self, _: &mut Formatter) -> fmt::Result {
unreachable!()
}
}
/// Like `SeqAccess`, but elements provide access to file descriptors
/// as well as data.
pub trait SeqAccessWithFds<'de> {
/// Like `SeqAccess::Error`.
type Error: Error;
/// Like `SeqAccess::next_element_seed`, but `seed` is a
/// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeWithFdsSeed<'de>;
/// Like `SeqAccess::next_element`, but returns a
/// `DeserializeWithFds` instead of a `Deserialize`.
fn next_element<T: DeserializeWithFds<'de>>(&mut self) -> Result<Option<T>, Self::Error> {
self.next_element_seed(PhantomData)
}
/// See `SeqAccess::size_hint`.
fn size_hint(&self) -> Option<usize> {
None
}
/// Invite a `Visitor` to visit. The inverse of `Visitor::visit`.
///
/// The purpose of this indirection is to allow implementations to
/// control how `Visitor::visit_seq` is called. This means that
/// whatever way they get a `SeqAccess` to pass to it doesn't have
/// to be exposed publicly through the trait.
fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
}
impl<'de, 'fds, A, F> SeqAccessWithFds<'de> for WithFds<'fds, A, F>
where
A: SeqAccess<'de>,
F: Iterator<Item = Fd>,
{
type Error = A::Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeWithFdsSeed<'de>,
{
let wrapper = WithFds {
inner: seed,
fds: self.fds,
};
self.inner.next_element_seed(wrapper)
}
fn size_hint(&self) -> Option<usize> {
self.inner.size_hint()
}
fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_seq(self.inner)
}
}
/// Like `MapAccess`, but keys and values provide access to file
/// descriptors as well as data.
pub trait MapAccessWithFds<'de>: Sized {
/// Like `MapAccess::Error`.
type Error: Error;
/// Like `MapAccess::next_key_seed`, but `seed` is a
/// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: DeserializeWithFdsSeed<'de>;
/// Like `MapAccess::next_value_seed`, but `seed` is a
/// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: DeserializeWithFdsSeed<'de>;
/// Like `MapAccess::next_entry_seed`, but `kseed` and `vseed` are
/// `DeserializeWithFdsSeed` instead of `DeserializeSeed`.
fn next_entry_seed<K: DeserializeWithFdsSeed<'de>, V: DeserializeWithFdsSeed<'de>>(
&mut self,
kseed: K,
vseed: V,
) -> Result<Option<(K::Value, V::Value)>, Self::Error> {
match self.next_key_seed(kseed)? {
Some(key) => {
let value = self.next_value_seed(vseed)?;
Ok(Some((key, value)))
}
None => Ok(None),
}
}
/// Like `MapAccess::next_key`, but returns a `DeserializeWithFds`
/// instead of a `Deserialize`.
fn next_key<K: DeserializeWithFds<'de>>(&mut self) -> Result<Option<K>, Self::Error> {
self.next_key_seed(PhantomData)
}
/// Like `MapAccess::next_value`, but returns a `DeserializeWithFds`
/// instead of a `Deserialize`.
fn next_value<K: DeserializeWithFds<'de>>(&mut self) -> Result<Option<K>, Self::Error> {
self.next_value_seed(PhantomData)
}
/// Like `MapAccess:next_entry`, but return values are
/// `DeserializeWithFds` instead of `Deserialize`.
fn next_entry<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
where
K: DeserializeWithFds<'de>,
V: DeserializeWithFds<'de>,
{
self.next_entry_seed(PhantomData, PhantomData)
}
/// Like `MapAccess::size_hint`.
fn size_hint(&self) -> Option<usize> {
None
}
/// Invite a `Visitor` to visit. The inverse of `Visitor::visit`.
///
/// The purpose of this indirection is to allow implementations to
/// control how `Visitor::visit_map` is called. This means that
/// whatever way they get a `MapAccess` to pass to it doesn't have
/// to be exposed publicly through the trait.
fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
}
impl<'de, 'fds, A, F> MapAccessWithFds<'de> for WithFds<'fds, A, F>
where
A: MapAccess<'de>,
F: Iterator<Item = Fd>,
{
type Error = A::Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: DeserializeWithFdsSeed<'de>,
{
let wrapper = WithFds {
inner: seed,
fds: self.fds,
};
self.inner.next_key_seed(wrapper)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: DeserializeWithFdsSeed<'de>,
{
let wrapper = WithFds {
inner: seed,
fds: self.fds,
};
self.inner.next_value_seed(wrapper)
}
fn size_hint(&self) -> Option<usize> {
self.inner.size_hint()
}
fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_map(self.inner)
}
}
/// Like `EnumAccess`, but variants provide access to file descriptors
/// as well as data.
pub trait EnumAccessWithFds<'de>: Sized {
/// Like `EnumAccess::Error`.
type Error: Error;
/// Like `EnumAccess::Variant`, but also provides access to file
/// descriptors.
type Variant: VariantAccessWithFds<'de, Error = Self::Error>;
/// Like `EnumAccess::variant_seed`, but `seed` is a
/// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where
V: DeserializeSeed<'de>;
/// Like `EnumAccess::variant`, but returns a `DeserializeWithFds`
/// instead of a `Deserialize`.
fn variant<V>(self) -> Result<(V, Self::Variant), Self::Error>
where
V: Deserialize<'de>,
{
self.variant_seed(PhantomData)
}
/// Invite a `Visitor` to visit. The inverse of `Visitor::visit`.
///
/// The purpose of this indirection is to allow implementations to
/// control how `Visitor::visit_enum` is called. This means that
/// whatever way they get an `EnumAccess` to pass to it doesn't
/// have to be exposed publicly through the trait.
fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
}
impl<'fds, 'de, A, F> EnumAccessWithFds<'de> for WithFds<'fds, A, F>
where
A: EnumAccess<'de>,
F: Iterator<Item = Fd>,
{
type Error = A::Error;
type Variant = WithFds<'fds, A::Variant, F>;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where
V: DeserializeSeed<'de>,
{
let (value, variant) = self.inner.variant_seed(seed)?;
let variant_with_fds = WithFds {
inner: variant,
fds: self.fds,
};
Ok((value, variant_with_fds))
}
fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_enum(self.inner)
}
}
/// Like `VariantAccess`, but provides file descriptors as well as data.
pub trait VariantAccessWithFds<'de>: Sized {
/// Like `VariantAccess::Error`.
type Error: Error;
/// Like `VariantAccess::unit_variant`.
fn unit_variant(self) -> Result<(), Self::Error>;
/// Like `VariantAccess::newtype_variant_seed`, but `seed` is a
/// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeWithFdsSeed<'de>;
/// Like `VariantAccess::newtype_variant`, but returns a
/// `DeserializeWithFds` instead of a `Deserialize`.
fn newtype_variant<T: DeserializeWithFds<'de>>(self) -> Result<T, Self::Error> {
self.newtype_variant_seed(PhantomData)
}
/// Like `VariantAccess::struct_variant`, but returns a
/// `DeserializeWithFds` instead of a `Deserialize`.
fn struct_variant<V: VisitorWithFds<'de>>(
self,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>;
}
impl<'de, 'fds, A, F> VariantAccessWithFds<'de> for WithFds<'fds, A, F>
where
A: VariantAccess<'de>,
F: Iterator<Item = Fd>,
{
type Error = A::Error;
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeWithFdsSeed<'de>,
{
let wrapper = WithFds {
inner: seed,
fds: self.fds,
};
self.inner.newtype_variant_seed(wrapper)
}
fn unit_variant(self) -> Result<(), Self::Error> {
self.inner.unit_variant()
}
fn struct_variant<V: VisitorWithFds<'de>>(
self,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
let wrapper = WithFds {
inner: visitor,
fds: self.fds,
};
self.inner.struct_variant(fields, wrapper)
}
}
/// Like `Visitor`, but provides file descriptors as well as data.
pub trait VisitorWithFds<'de>: Sized {
/// Like `Visitor::Value`.
type Value;
/// Like `Visitor::expecting`.
fn expecting(&self, f: &mut Formatter) -> fmt::Result;
/// Like `Visitor::visit_none`.
fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
VisitorDefaults(PhantomData).visit_none()
}
/// Like `Visitor:::visit_some`, but `deserializer` is a
/// `DeserializerWithFds` instead of a `Deserializer`.
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: DeserializerWithFds<'de>,
{
deserializer.invite_visit_some(VisitorDefaults(PhantomData))
}
/// Like `Visitor::visit_seq`, but `seq` is a `SeqAccessWithFds`
/// instead of a `SeqAccess`.
fn visit_seq<A: SeqAccessWithFds<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
seq.invite(VisitorDefaults(PhantomData))
}
/// Like `Visitor::visit_map`, but `map` is a `MapAccessWithFds`
/// instead of a `MapAccess`.
fn visit_map<A: MapAccessWithFds<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
map.invite(VisitorDefaults(PhantomData))
}
/// Like `Visitor::visit_enum`, but `data` is an
/// `EnumAccessWithFds` instead of an `EnumAccess`.
fn visit_enum<A: EnumAccessWithFds<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
data.invite(VisitorDefaults(PhantomData))
}
}
impl<'de, 'fds, V, F> Visitor<'de> for WithFds<'fds, V, F>
where
V: VisitorWithFds<'de>,
F: Iterator<Item = Fd>,
{
type Value = V::Value;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
self.inner.expecting(f)
}
fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
self.inner.visit_none()
}
fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
self.inner.visit_some(WithFds {
inner: deserializer,
fds: self.fds,
})
}
fn visit_seq<A: SeqAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
self.inner.visit_seq(WithFds {
inner: data,
fds: self.fds,
})
}
fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
self.inner.visit_map(WithFds {
inner: map,
fds: self.fds,
})
}
fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
self.inner.visit_enum(WithFds {
inner: data,
fds: self.fds,
})
}
}
macro_rules! deserialize_impl {
($type:ty) => {
impl<'de> DeserializeWithFds<'de> for $type {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: DeserializerWithFds<'de>,
{
deserializer.invite_deserialize()
}
}
};
}
macro_rules! fd_impl {
($type:ty) => {
impl<'de> DeserializeWithFds<'de> for $type {
fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_fd().map(|x| x.specialize())
}
}
};
}
deserialize_impl!(());
deserialize_impl!(u8);
deserialize_impl!(u16);
deserialize_impl!(u32);
deserialize_impl!(u64);
deserialize_impl!(usize);
deserialize_impl!(String);
deserialize_impl!(std::path::PathBuf);
fd_impl!(std::fs::File);
fd_impl!(std::net::TcpListener);
fd_impl!(std::net::TcpStream);
fd_impl!(std::net::UdpSocket);
fd_impl!(std::os::unix::net::UnixDatagram);
fd_impl!(std::os::unix::net::UnixListener);
fd_impl!(std::os::unix::net::UnixStream);
fd_impl!(sys_util::net::UnixSeqpacket);
impl<'de, T: DeserializeWithFds<'de>> DeserializeWithFds<'de> for Option<T> {
fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct Visitor<T>(PhantomData<T>);
impl<'de, T: DeserializeWithFds<'de>> VisitorWithFds<'de> for Visitor<T> {
type Value = Option<T>;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "option")
}
fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: DeserializerWithFds<'de>,
{
T::deserialize(deserializer).map(Some)
}
}
deserializer.deserialize_option(Visitor(PhantomData))
}
}
impl<'de, T: DeserializeWithFds<'de>> DeserializeWithFds<'de> for Vec<T> {
fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct Visitor<T>(PhantomData<T>);
impl<'de, T: DeserializeWithFds<'de>> VisitorWithFds<'de> for Visitor<T> {
type Value = Vec<T>;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccessWithFds<'de>,
{
let mut values = Vec::with_capacity(min(seq.size_hint().unwrap_or(0), 4096));
while let Some(value) = seq.next_element()? {
values.push(value);
}
Ok(values)
}
}
deserializer.deserialize_seq(Visitor(PhantomData))
}
}
impl<'de, K, V> DeserializeWithFds<'de> for BTreeMap<K, V>
where
K: DeserializeWithFds<'de> + Ord,
V: DeserializeWithFds<'de>,
{
fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct Visitor<K, V>(PhantomData<(K, V)>);
impl<'de, K, V> VisitorWithFds<'de> for Visitor<K, V>
where
K: DeserializeWithFds<'de> + Ord,
V: DeserializeWithFds<'de>,
{
type Value = BTreeMap<K, V>;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "a map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccessWithFds<'de>,
{
let mut values = BTreeMap::new();
while let Some((key, value)) = map.next_entry()? {
values.insert(key, value);
}
Ok(values)
}
}
deserializer.deserialize_map(Visitor(PhantomData))
}
}