libp2p_core/transport/
map_err.rs1use crate::transport::{ListenerId, Transport, TransportError, TransportEvent};
22use futures::prelude::*;
23use multiaddr::Multiaddr;
24use std::{error, pin::Pin, task::Context, task::Poll};
25
26#[derive(Debug, Copy, Clone)]
28#[pin_project::pin_project]
29pub struct MapErr<T, F> {
30 #[pin]
31 transport: T,
32 map: F,
33}
34
35impl<T, F> MapErr<T, F> {
36 pub(crate) fn new(transport: T, map: F) -> MapErr<T, F> {
38 MapErr { transport, map }
39 }
40}
41
42impl<T, F, TErr> Transport for MapErr<T, F>
43where
44 T: Transport,
45 F: FnOnce(T::Error) -> TErr + Clone,
46 TErr: error::Error,
47{
48 type Output = T::Output;
49 type Error = TErr;
50 type ListenerUpgrade = MapErrListenerUpgrade<T, F>;
51 type Dial = MapErrDial<T, F>;
52
53 fn listen_on(
54 &mut self,
55 id: ListenerId,
56 addr: Multiaddr,
57 ) -> Result<(), TransportError<Self::Error>> {
58 let map = self.map.clone();
59 self.transport
60 .listen_on(id, addr)
61 .map_err(|err| err.map(map))
62 }
63
64 fn remove_listener(&mut self, id: ListenerId) -> bool {
65 self.transport.remove_listener(id)
66 }
67
68 fn dial(&mut self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
69 let map = self.map.clone();
70 match self.transport.dial(addr) {
71 Ok(future) => Ok(MapErrDial {
72 inner: future,
73 map: Some(map),
74 }),
75 Err(err) => Err(err.map(map)),
76 }
77 }
78
79 fn dial_as_listener(
80 &mut self,
81 addr: Multiaddr,
82 ) -> Result<Self::Dial, TransportError<Self::Error>> {
83 let map = self.map.clone();
84 match self.transport.dial_as_listener(addr) {
85 Ok(future) => Ok(MapErrDial {
86 inner: future,
87 map: Some(map),
88 }),
89 Err(err) => Err(err.map(map)),
90 }
91 }
92
93 fn address_translation(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
94 self.transport.address_translation(server, observed)
95 }
96
97 fn poll(
98 self: Pin<&mut Self>,
99 cx: &mut Context<'_>,
100 ) -> Poll<TransportEvent<Self::ListenerUpgrade, Self::Error>> {
101 let this = self.project();
102 let map = &*this.map;
103 this.transport.poll(cx).map(|ev| {
104 ev.map_upgrade(move |value| MapErrListenerUpgrade {
105 inner: value,
106 map: Some(map.clone()),
107 })
108 .map_err(map.clone())
109 })
110 }
111}
112
113#[pin_project::pin_project]
115pub struct MapErrListenerUpgrade<T: Transport, F> {
116 #[pin]
117 inner: T::ListenerUpgrade,
118 map: Option<F>,
119}
120
121impl<T, F, TErr> Future for MapErrListenerUpgrade<T, F>
122where
123 T: Transport,
124 F: FnOnce(T::Error) -> TErr,
125{
126 type Output = Result<T::Output, TErr>;
127
128 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
129 let this = self.project();
130 match Future::poll(this.inner, cx) {
131 Poll::Ready(Ok(value)) => Poll::Ready(Ok(value)),
132 Poll::Pending => Poll::Pending,
133 Poll::Ready(Err(err)) => {
134 let map = this.map.take().expect("poll() called again after error");
135 Poll::Ready(Err(map(err)))
136 }
137 }
138 }
139}
140
141#[pin_project::pin_project]
143pub struct MapErrDial<T: Transport, F> {
144 #[pin]
145 inner: T::Dial,
146 map: Option<F>,
147}
148
149impl<T, F, TErr> Future for MapErrDial<T, F>
150where
151 T: Transport,
152 F: FnOnce(T::Error) -> TErr,
153{
154 type Output = Result<T::Output, TErr>;
155
156 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
157 let this = self.project();
158 match Future::poll(this.inner, cx) {
159 Poll::Ready(Ok(value)) => Poll::Ready(Ok(value)),
160 Poll::Pending => Poll::Pending,
161 Poll::Ready(Err(err)) => {
162 let map = this.map.take().expect("poll() called again after error");
163 Poll::Ready(Err(map(err)))
164 }
165 }
166 }
167}