use std::fmt::{self, Formatter}; use std::fs::File; use msg_socket2::{ de::{SeqAccessWithFds, VisitorWithFds}, ser::{ SerializeAdapter, SerializeStruct, SerializeStructFds, SerializeTupleStruct, SerializeTupleStructFds, }, DeserializeWithFds, DeserializerWithFds, FdSerializer, SerializeWithFds, Serializer, Socket, }; use sys_util::net::UnixSeqpacket; #[derive(Debug)] struct Inner(File, u16); impl SerializeWithFds for Inner { fn serialize(&self, serializer: S) -> Result { let mut state = serializer.serialize_tuple_struct("Inner", 1)?; state.serialize_field(&self.1)?; state.end() } fn serialize_fds<'fds, S: FdSerializer<'fds>>( &'fds self, serializer: S, ) -> Result { let mut state = serializer.serialize_tuple_struct("Inner", 1)?; state.serialize_field(&self.0)?; state.end() } } impl<'de> DeserializeWithFds<'de> for Inner { fn deserialize(deserializer: D) -> Result where D: DeserializerWithFds<'de>, { struct Visitor; impl<'de> VisitorWithFds<'de> for Visitor { type Value = Inner; fn expecting(&self, f: &mut Formatter) -> fmt::Result { write!(f, "struct Inner") } fn visit_seq(self, mut seq: A) -> Result where A: SeqAccessWithFds<'de>, { Ok(Inner( seq.next_element()?.unwrap(), seq.next_element()?.unwrap(), )) } } deserializer.deserialize_tuple_struct("Inner", 2, Visitor) } } #[derive(Debug)] struct Test { fd: File, inner: Inner, } impl SerializeWithFds for Test { fn serialize(&self, serializer: Ser) -> Result { let mut state = serializer.serialize_struct("Test", 1)?; state.skip_field("fd")?; state.serialize_field("inner", &SerializeAdapter::new(&self.inner))?; state.end() } fn serialize_fds<'fds, S: FdSerializer<'fds>>( &'fds self, serializer: S, ) -> Result { let mut state = serializer.serialize_struct("Test", 2)?; state.serialize_field("fd", &self.fd)?; state.serialize_field("inner", &self.inner)?; state.end() } } impl<'de> DeserializeWithFds<'de> for Test { fn deserialize(deserializer: D) -> Result where D: DeserializerWithFds<'de>, { struct Visitor; impl<'de> VisitorWithFds<'de> for Visitor { type Value = Test; fn expecting(&self, f: &mut Formatter) -> fmt::Result { write!(f, "struct Test") } fn visit_seq(self, mut seq: A) -> Result where A: SeqAccessWithFds<'de>, { Ok(Test { fd: seq.next_element()?.unwrap(), inner: seq.next_element()?.unwrap(), }) } } deserializer.deserialize_struct("Test", &["fd", "inner"], Visitor) } } #[test] fn round_trip() { let (f1, f2) = UnixSeqpacket::pair().unwrap(); let s1: Socket<_, ()> = Socket::new(f1); let s2: Socket<(), Test> = Socket::new(f2); s1.send(Test { fd: File::open("/dev/null").unwrap(), inner: Inner(File::open("/dev/null").unwrap(), 0xACAB), }) .unwrap(); let result = s2.recv().unwrap(); assert_eq!(result.inner.1, 0xACAB); }