libp2p_core/transport/
map_err.rs1use crate::transport::{DialOpts, 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(
69 &mut self,
70 addr: Multiaddr,
71 opts: DialOpts,
72 ) -> Result<Self::Dial, TransportError<Self::Error>> {
73 let map = self.map.clone();
74 match self.transport.dial(addr, opts) {
75 Ok(future) => Ok(MapErrDial {
76 inner: future,
77 map: Some(map),
78 }),
79 Err(err) => Err(err.map(map)),
80 }
81 }
82
83 fn poll(
84 self: Pin<&mut Self>,
85 cx: &mut Context<'_>,
86 ) -> Poll<TransportEvent<Self::ListenerUpgrade, Self::Error>> {
87 let this = self.project();
88 let map = &*this.map;
89 this.transport.poll(cx).map(|ev| {
90 ev.map_upgrade(move |value| MapErrListenerUpgrade {
91 inner: value,
92 map: Some(map.clone()),
93 })
94 .map_err(map.clone())
95 })
96 }
97}
98
99#[pin_project::pin_project]
101pub struct MapErrListenerUpgrade<T: Transport, F> {
102 #[pin]
103 inner: T::ListenerUpgrade,
104 map: Option<F>,
105}
106
107impl<T, F, TErr> Future for MapErrListenerUpgrade<T, F>
108where
109 T: Transport,
110 F: FnOnce(T::Error) -> TErr,
111{
112 type Output = Result<T::Output, TErr>;
113
114 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
115 let this = self.project();
116 match Future::poll(this.inner, cx) {
117 Poll::Ready(Ok(value)) => Poll::Ready(Ok(value)),
118 Poll::Pending => Poll::Pending,
119 Poll::Ready(Err(err)) => {
120 let map = this.map.take().expect("poll() called again after error");
121 Poll::Ready(Err(map(err)))
122 }
123 }
124 }
125}
126
127#[pin_project::pin_project]
129pub struct MapErrDial<T: Transport, F> {
130 #[pin]
131 inner: T::Dial,
132 map: Option<F>,
133}
134
135impl<T, F, TErr> Future for MapErrDial<T, F>
136where
137 T: Transport,
138 F: FnOnce(T::Error) -> TErr,
139{
140 type Output = Result<T::Output, TErr>;
141
142 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
143 let this = self.project();
144 match Future::poll(this.inner, cx) {
145 Poll::Ready(Ok(value)) => Poll::Ready(Ok(value)),
146 Poll::Pending => Poll::Pending,
147 Poll::Ready(Err(err)) => {
148 let map = this.map.take().expect("poll() called again after error");
149 Poll::Ready(Err(map(err)))
150 }
151 }
152 }
153}