qiniu_http_client/client/chooser/
mod.rs1mod direct;
2mod feedback;
3mod ip;
4mod never_empty_handed;
5mod shuffled;
6mod subnet;
7
8use super::super::regions::{DomainWithPort, IpAddrWithPort};
9use auto_impl::auto_impl;
10use dyn_clonable::clonable;
11pub use feedback::ChooserFeedback;
12use std::{
13 fmt::Debug,
14 ops::{Deref, DerefMut},
15};
16
17#[cfg(feature = "async")]
18use futures::future::BoxFuture;
19
20#[clonable]
26#[auto_impl(&, &mut, Box, Rc, Arc)]
27pub trait Chooser: Clone + Debug + Sync + Send {
28 fn choose(&self, ips: &[IpAddrWithPort], opts: ChooseOptions) -> ChosenResults;
30
31 fn feedback(&self, feedback: ChooserFeedback);
33
34 #[inline]
38 #[cfg(feature = "async")]
39 #[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
40 fn async_choose<'a>(&'a self, ips: &'a [IpAddrWithPort], opts: ChooseOptions<'a>) -> BoxFuture<'a, ChosenResults> {
41 Box::pin(async move { self.choose(ips, opts) })
42 }
43
44 #[inline]
46 #[cfg(feature = "async")]
47 #[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
48 fn async_feedback<'a>(&'a self, feedback: ChooserFeedback<'a>) -> BoxFuture<'a, ()> {
49 Box::pin(async move { self.feedback(feedback) })
50 }
51}
52
53#[derive(Debug, Copy, Clone, Default)]
55pub struct ChooseOptions<'a> {
56 domain: Option<&'a DomainWithPort>,
57}
58
59impl<'a> ChooseOptions<'a> {
60 #[inline]
62 pub fn domain(&'a self) -> Option<&'a DomainWithPort> {
63 self.domain
64 }
65
66 #[inline]
68 pub fn builder() -> ChooseOptionsBuilder<'a> {
69 ChooseOptionsBuilder::new()
70 }
71}
72
73#[derive(Debug, Clone, Default)]
75pub struct ChooseOptionsBuilder<'a>(ChooseOptions<'a>);
76
77impl<'a> ChooseOptionsBuilder<'a> {
78 #[inline]
80 pub fn new() -> Self {
81 Self::default()
82 }
83
84 #[inline]
86 pub fn domain(&mut self, domain: &'a DomainWithPort) -> &mut Self {
87 self.0.domain = Some(domain);
88 self
89 }
90
91 #[inline]
93 pub fn build(&self) -> ChooseOptions<'a> {
94 self.0
95 }
96}
97
98#[derive(Debug)]
100pub struct ChosenResults(Vec<IpAddrWithPort>);
101
102impl ChosenResults {
103 #[inline]
105 pub fn ip_addrs(&self) -> &[IpAddrWithPort] {
106 &self.0
107 }
108
109 #[inline]
111 pub fn ip_addrs_mut(&mut self) -> &mut Vec<IpAddrWithPort> {
112 &mut self.0
113 }
114
115 #[inline]
117 pub fn into_ip_addrs(self) -> Vec<IpAddrWithPort> {
118 self.0
119 }
120}
121
122impl From<Vec<IpAddrWithPort>> for ChosenResults {
123 #[inline]
124 fn from(ip_addrs: Vec<IpAddrWithPort>) -> Self {
125 Self(ip_addrs)
126 }
127}
128
129impl FromIterator<IpAddrWithPort> for ChosenResults {
130 #[inline]
131 fn from_iter<T: IntoIterator<Item = IpAddrWithPort>>(iter: T) -> Self {
132 Self(Vec::from_iter(iter))
133 }
134}
135
136impl<'a> IntoIterator for &'a ChosenResults {
137 type Item = &'a IpAddrWithPort;
138 type IntoIter = std::slice::Iter<'a, IpAddrWithPort>;
139
140 #[inline]
141 fn into_iter(self) -> Self::IntoIter {
142 self.0.iter()
143 }
144}
145
146impl IntoIterator for ChosenResults {
147 type Item = IpAddrWithPort;
148 type IntoIter = std::vec::IntoIter<IpAddrWithPort>;
149
150 #[inline]
151 fn into_iter(self) -> Self::IntoIter {
152 self.0.into_iter()
153 }
154}
155
156impl From<ChosenResults> for Vec<IpAddrWithPort> {
157 #[inline]
158 fn from(answers: ChosenResults) -> Self {
159 answers.0
160 }
161}
162
163impl AsRef<[IpAddrWithPort]> for ChosenResults {
164 #[inline]
165 fn as_ref(&self) -> &[IpAddrWithPort] {
166 &self.0
167 }
168}
169
170impl AsMut<[IpAddrWithPort]> for ChosenResults {
171 #[inline]
172 fn as_mut(&mut self) -> &mut [IpAddrWithPort] {
173 &mut self.0
174 }
175}
176
177impl Deref for ChosenResults {
178 type Target = [IpAddrWithPort];
179
180 #[inline]
181 fn deref(&self) -> &Self::Target {
182 &self.0
183 }
184}
185
186impl DerefMut for ChosenResults {
187 #[inline]
188 fn deref_mut(&mut self) -> &mut Self::Target {
189 &mut self.0
190 }
191}
192
193pub use direct::DirectChooser;
194pub use ip::{IpChooser, IpChooserBuilder};
195pub use never_empty_handed::NeverEmptyHandedChooser;
196pub use shuffled::ShuffledChooser;
197pub use subnet::{SubnetChooser, SubnetChooserBuilder};