mod direct;
mod feedback;
mod ip;
mod never_empty_handed;
mod shuffled;
mod subnet;
use super::super::regions::{DomainWithPort, IpAddrWithPort};
use auto_impl::auto_impl;
use dyn_clonable::clonable;
pub use feedback::ChooserFeedback;
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
#[cfg(feature = "async")]
use futures::future::BoxFuture;
#[clonable]
#[auto_impl(&, &mut, Box, Rc, Arc)]
pub trait Chooser: Clone + Debug + Sync + Send {
fn choose(&self, ips: &[IpAddrWithPort], opts: ChooseOptions) -> ChosenResults;
fn feedback(&self, feedback: ChooserFeedback);
#[inline]
#[cfg(feature = "async")]
#[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
fn async_choose<'a>(&'a self, ips: &'a [IpAddrWithPort], opts: ChooseOptions<'a>) -> BoxFuture<'a, ChosenResults> {
Box::pin(async move { self.choose(ips, opts) })
}
#[inline]
#[cfg(feature = "async")]
#[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
fn async_feedback<'a>(&'a self, feedback: ChooserFeedback<'a>) -> BoxFuture<'a, ()> {
Box::pin(async move { self.feedback(feedback) })
}
}
#[derive(Debug, Copy, Clone, Default)]
pub struct ChooseOptions<'a> {
domain: Option<&'a DomainWithPort>,
}
impl<'a> ChooseOptions<'a> {
#[inline]
pub fn domain(&'a self) -> Option<&'a DomainWithPort> {
self.domain
}
#[inline]
pub fn builder() -> ChooseOptionsBuilder<'a> {
ChooseOptionsBuilder::new()
}
}
#[derive(Debug, Clone, Default)]
pub struct ChooseOptionsBuilder<'a>(ChooseOptions<'a>);
impl<'a> ChooseOptionsBuilder<'a> {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn domain(&mut self, domain: &'a DomainWithPort) -> &mut Self {
self.0.domain = Some(domain);
self
}
#[inline]
pub fn build(&self) -> ChooseOptions<'a> {
self.0
}
}
#[derive(Debug)]
pub struct ChosenResults(Vec<IpAddrWithPort>);
impl ChosenResults {
#[inline]
pub fn ip_addrs(&self) -> &[IpAddrWithPort] {
&self.0
}
#[inline]
pub fn ip_addrs_mut(&mut self) -> &mut Vec<IpAddrWithPort> {
&mut self.0
}
#[inline]
pub fn into_ip_addrs(self) -> Vec<IpAddrWithPort> {
self.0
}
}
impl From<Vec<IpAddrWithPort>> for ChosenResults {
#[inline]
fn from(ip_addrs: Vec<IpAddrWithPort>) -> Self {
Self(ip_addrs)
}
}
impl FromIterator<IpAddrWithPort> for ChosenResults {
#[inline]
fn from_iter<T: IntoIterator<Item = IpAddrWithPort>>(iter: T) -> Self {
Self(Vec::from_iter(iter))
}
}
impl<'a> IntoIterator for &'a ChosenResults {
type Item = &'a IpAddrWithPort;
type IntoIter = std::slice::Iter<'a, IpAddrWithPort>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl IntoIterator for ChosenResults {
type Item = IpAddrWithPort;
type IntoIter = std::vec::IntoIter<IpAddrWithPort>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl From<ChosenResults> for Vec<IpAddrWithPort> {
#[inline]
fn from(answers: ChosenResults) -> Self {
answers.0
}
}
impl AsRef<[IpAddrWithPort]> for ChosenResults {
#[inline]
fn as_ref(&self) -> &[IpAddrWithPort] {
&self.0
}
}
impl AsMut<[IpAddrWithPort]> for ChosenResults {
#[inline]
fn as_mut(&mut self) -> &mut [IpAddrWithPort] {
&mut self.0
}
}
impl Deref for ChosenResults {
type Target = [IpAddrWithPort];
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for ChosenResults {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub use direct::DirectChooser;
pub use ip::{IpChooser, IpChooserBuilder};
pub use never_empty_handed::NeverEmptyHandedChooser;
pub use shuffled::ShuffledChooser;
pub use subnet::{SubnetChooser, SubnetChooserBuilder};