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