summary refs log blame commit diff
path: root/msg_socket2/src/de.rs
blob: 67073c0f0cac7a40eefe612f59ff35125503d7ee (plain) (tree)
1
2
3
4
5
6
7





                                                       
 











                                                                     
                                                                                                  













                                                                           
                                          
























































                                                                                                  
         





                                                                                                  

                                                                    












































































































                                                                                                  
                                        



















































                                                                                                

 



                                                                    
                



































































                                                                                              

 













                                                                                    
                                                                              








                                                                                       








                                                            




































                                                                                            







































                                                                                    

















































































































































































                                                                                              










                                                                                                 






                                                                                     






                                                                                    












































































































































                                                                                                    

     
// 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))
    }
}