|
1 |
| -use std::fmt; |
2 | 1 | use std::marker::PhantomData;
|
3 | 2 |
|
4 | 3 | use super::{Connector, Transport};
|
5 | 4 |
|
6 |
| -/// Two chained connectors called one after another. |
| 5 | +/// Chain of up to 8 connectors |
7 | 6 | ///
|
8 |
| -/// Created by calling [`Connector::chain`] on the first connector. |
9 |
| -pub struct ChainedConnector<In, First, Second>(First, Second, PhantomData<In>); |
10 |
| - |
11 |
| -impl<In, First, Second> Connector<In> for ChainedConnector<In, First, Second> |
12 |
| -where |
13 |
| - In: Transport, |
14 |
| - First: Connector<In>, |
15 |
| - Second: Connector<First::Out>, |
16 |
| -{ |
17 |
| - type Out = Second::Out; |
18 |
| - |
19 |
| - fn connect( |
20 |
| - &self, |
21 |
| - details: &super::ConnectionDetails, |
22 |
| - chained: Option<In>, |
23 |
| - ) -> Result<Option<Self::Out>, crate::Error> { |
24 |
| - let f_out = self.0.connect(details, chained)?; |
25 |
| - self.1.connect(details, f_out) |
| 7 | +/// Can be created manually from a tuple of connectors through `ChainedConnector::new` |
| 8 | +#[derive(Debug)] |
| 9 | +pub struct ChainedConnector<In, Connectors>(Connectors, PhantomData<In>); |
| 10 | + |
| 11 | +impl<In, Connectors> ChainedConnector<In, Connectors> { |
| 12 | + /// Create a new chained connector that chains a tuple of connectors |
| 13 | + /// |
| 14 | + /// ```rust |
| 15 | + /// # use ureq::unversioned::transport::{ChainedConnector, SocsConnector, TcpConnector, RustlsConnector, ConnectProxyConnector}; |
| 16 | + /// let connector: ChainedConnector<(), (SocsConnector, TcpConnector, RustlsConnector, ConnectProxyConnector)> = ChainedConnector::new(SocsConnector::default(), TcpConnector::default(), RustlsConnector::default(), ConnectProxyConnector::default()); |
| 17 | + /// ``` |
| 18 | + pub fn new(connectors: Connectors) -> Self { |
| 19 | + Self(connectors, PhantomData) |
26 | 20 | }
|
27 | 21 | }
|
28 | 22 |
|
29 |
| -impl<In, First, Second> ChainedConnector<In, First, Second> { |
30 |
| - pub(crate) fn new(first: First, second: Second) -> Self { |
31 |
| - ChainedConnector(first, second, PhantomData) |
32 |
| - } |
33 |
| -} |
| 23 | +macro_rules! impl_chained_connectors { |
| 24 | + (($first_ty:ident, $first_name: ident) ; $(($ty:ident, $name:ident, $prev_ty:ident)),* ; ($final_ty:ident, $final_name: ident, $pre_final_ty:ident)) => { |
| 25 | + impl<In, $first_ty, $($ty,)* $final_ty> Connector<In> for ChainedConnector<In, ($first_ty, $($ty,)* $final_ty)> |
| 26 | + where |
| 27 | + In: Transport, |
| 28 | + $first_ty: Connector<In>, |
| 29 | + $($ty: Connector<$prev_ty::Out>,)* |
| 30 | + $final_ty: Connector<$pre_final_ty::Out>, |
| 31 | + { |
| 32 | + type Out = $final_ty::Out; |
| 33 | + fn connect( |
| 34 | + &self, |
| 35 | + details: &super::ConnectionDetails, |
| 36 | + chained: Option<In>, |
| 37 | + ) -> Result<Option<Self::Out>, crate::Error> { |
| 38 | + let ChainedConnector(( |
| 39 | + ref $first_name, |
| 40 | + $(ref $name,)* |
| 41 | + ref $final_name, |
| 42 | + ), _) = self; |
| 43 | + |
| 44 | + let out = $first_name.connect(details, chained)?; |
| 45 | + $( |
| 46 | + let out = $name.connect(details, out)?; |
| 47 | + )* |
| 48 | + $final_name.connect(details,out) |
| 49 | + } |
| 50 | + } |
34 | 51 |
|
35 |
| -impl<In, First, Second> fmt::Debug for ChainedConnector<In, First, Second> |
36 |
| -where |
37 |
| - In: Transport, |
38 |
| - First: Connector<In>, |
39 |
| - Second: Connector<First::Out>, |
40 |
| -{ |
41 |
| - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
42 |
| - f.debug_tuple("ChainedConnector") |
43 |
| - .field(&self.0) |
44 |
| - .field(&self.1) |
45 |
| - .finish() |
46 |
| - } |
| 52 | + }; |
47 | 53 | }
|
48 | 54 |
|
| 55 | +impl_chained_connectors!( |
| 56 | + (A, a) ; |
| 57 | + (B, b, A), |
| 58 | + (C, c, B), |
| 59 | + (D, d, C), |
| 60 | + (E, e, D), |
| 61 | + (F, f, E), |
| 62 | + (G, g, F); |
| 63 | + (H, h, G) |
| 64 | +); |
| 65 | + |
| 66 | +impl_chained_connectors!( |
| 67 | + (A, a) ; |
| 68 | + (B, b, A), |
| 69 | + (C, c, B), |
| 70 | + (D, d, C), |
| 71 | + (E, e, D), |
| 72 | + (F, f, E); |
| 73 | + (G, g, F) |
| 74 | +); |
| 75 | + |
| 76 | +impl_chained_connectors!( |
| 77 | + (A, a) ; |
| 78 | + (B, b, A), |
| 79 | + (C, c, B), |
| 80 | + (D, d, C), |
| 81 | + (E, e, D); |
| 82 | + (F, f, E) |
| 83 | +); |
| 84 | + |
| 85 | +impl_chained_connectors!( |
| 86 | + (A, a) ; |
| 87 | + (B, b, A), |
| 88 | + (C, c, B), |
| 89 | + (D, d, C); |
| 90 | + (E, e, D) |
| 91 | +); |
| 92 | +impl_chained_connectors!( |
| 93 | + (A, a) ; |
| 94 | + (B, b, A), |
| 95 | + (C, c, B); |
| 96 | + (D, d, C) |
| 97 | +); |
| 98 | +impl_chained_connectors!( |
| 99 | + (A, a) ; |
| 100 | + (B, b, A); |
| 101 | + (C, c, B) |
| 102 | +); |
| 103 | +impl_chained_connectors!( |
| 104 | + (A, a) ;; |
| 105 | + (B, b, A) |
| 106 | +); |
| 107 | +// impl<In, First, Second> Connector<In> for ChainedConnector<In, First, Second> |
| 108 | +// where |
| 109 | +// In: Transport, |
| 110 | +// First: Connector<In>, |
| 111 | +// Second: Connector<First::Out>, |
| 112 | +// { |
| 113 | +// type Out = Second::Out; |
| 114 | + |
| 115 | +// fn connect( |
| 116 | +// &self, |
| 117 | +// details: &super::ConnectionDetails, |
| 118 | +// chained: Option<In>, |
| 119 | +// ) -> Result<Option<Self::Out>, crate::Error> { |
| 120 | +// let f_out = self.0.connect(details, chained)?; |
| 121 | +// self.1.connect(details, f_out) |
| 122 | +// } |
| 123 | +// } |
| 124 | + |
49 | 125 | /// A selection between two transports.
|
50 | 126 | #[derive(Debug)]
|
51 | 127 | pub enum Either<A, B> {
|
|
0 commit comments