qiniu_http_client/client/chooser/
mod.rs

1mod 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/// 选择 IP 地址接口
21///
22/// 还提供了对选择结果的反馈接口,用以修正自身选择逻辑,优化选择结果
23///
24/// 同时提供阻塞接口和异步接口,异步接口则需要启用 `async` 功能
25#[clonable]
26#[auto_impl(&, &mut, Box, Rc, Arc)]
27pub trait Chooser: Clone + Debug + Sync + Send {
28    /// 选择 IP 地址列表
29    fn choose(&self, ips: &[IpAddrWithPort], opts: ChooseOptions) -> ChosenResults;
30
31    /// 反馈选择的 IP 地址列表的结果
32    fn feedback(&self, feedback: ChooserFeedback);
33
34    /// 异步选择 IP 地址列表
35    ///
36    /// 该方法的异步版本为 [`Self::async_choose`]。
37    #[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    /// 异步反馈选择的 IP 地址列表的结果
45    #[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/// 选择 IP 地址列表的选项
54#[derive(Debug, Copy, Clone, Default)]
55pub struct ChooseOptions<'a> {
56    domain: Option<&'a DomainWithPort>,
57}
58
59impl<'a> ChooseOptions<'a> {
60    /// 获取 IP 地址的域名
61    #[inline]
62    pub fn domain(&'a self) -> Option<&'a DomainWithPort> {
63        self.domain
64    }
65
66    /// 创建选择 IP 地址列表的选项构建器
67    #[inline]
68    pub fn builder() -> ChooseOptionsBuilder<'a> {
69        ChooseOptionsBuilder::new()
70    }
71}
72
73/// 选择 IP 地址列表的选项构建器
74#[derive(Debug, Clone, Default)]
75pub struct ChooseOptionsBuilder<'a>(ChooseOptions<'a>);
76
77impl<'a> ChooseOptionsBuilder<'a> {
78    /// 创建选择 IP 地址列表的选项构建器
79    #[inline]
80    pub fn new() -> Self {
81        Self::default()
82    }
83
84    /// 设置 IP 地址的域名
85    #[inline]
86    pub fn domain(&mut self, domain: &'a DomainWithPort) -> &mut Self {
87        self.0.domain = Some(domain);
88        self
89    }
90
91    /// 构建选择 IP 地址列表的选项
92    #[inline]
93    pub fn build(&self) -> ChooseOptions<'a> {
94        self.0
95    }
96}
97
98/// 经过选择的 IP 地址列表
99#[derive(Debug)]
100pub struct ChosenResults(Vec<IpAddrWithPort>);
101
102impl ChosenResults {
103    /// 获取 IP 地址列表
104    #[inline]
105    pub fn ip_addrs(&self) -> &[IpAddrWithPort] {
106        &self.0
107    }
108
109    /// 获取 IP 地址列表的可变引用
110    #[inline]
111    pub fn ip_addrs_mut(&mut self) -> &mut Vec<IpAddrWithPort> {
112        &mut self.0
113    }
114
115    /// 转换为 IP 地址列表
116    #[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};