top_gg/client/request/
search_bots.rs

1use super::Pending;
2use crate::{
3    client::{self, Client},
4    endpoints,
5    error::Result,
6    model::{Bot, SearchResponse},
7};
8use std::{
9    collections::HashMap,
10    fmt::Display,
11    future::Future,
12    pin::Pin,
13    task::{Context, Poll},
14};
15
16/// Request to search for a list of bots given some parameters.
17///
18/// Refer to [`Client::get_bots`] for more information.
19///
20/// [`Client::get_bots`]: ../struct.Client.html#method.get_bots
21pub struct SearchBots<'a> {
22    client: &'a Client,
23    fut: Option<Pending<'a, Result<SearchResponse<Bot>>>>,
24    params: HashMap<&'static str, String>,
25}
26
27impl<'a> SearchBots<'a> {
28    pub(crate) fn new(client: &'a Client) -> Self {
29        Self {
30            client,
31            fut: None,
32            params: HashMap::new(),
33        }
34    }
35
36    /// The amount of bots to return, used for pagination.
37    ///
38    /// The maximum value is 500.
39    pub fn limit(mut self, mut limit: u16) -> Self {
40        if limit > 500 {
41            limit = 500;
42        }
43
44        self.params.insert("limit", limit.to_string());
45
46        self
47    }
48
49    /// The amount of bots to skip, used for pagination.
50    pub fn offset(mut self, offset: u64) -> Self {
51        self.params.insert("offset", offset.to_string());
52
53        self
54    }
55
56    /// A search query string.
57    pub fn search(self, query: impl Into<String>) -> Self {
58        self._search(query.into())
59    }
60
61    fn _search(mut self, query: String) -> Self {
62        self.params.insert("search", query);
63
64        self
65    }
66
67    /// The field to sort by.
68    pub fn sort(mut self, field: impl Display, ascending: bool) -> Self {
69        let prefix = if ascending { "" } else { "-" };
70
71        self.params.insert("sort", format!("{}{}", prefix, field));
72
73        self
74    }
75
76    fn start(&mut self) -> Result<()> {
77        let url = client::url(endpoints::bots())?;
78
79        self.fut.replace(Box::pin(self.client.get(url)));
80
81        Ok(())
82    }
83}
84
85impl Future for SearchBots<'_> {
86    type Output = Result<SearchResponse<Bot>>;
87
88    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
89        loop {
90            if let Some(fut) = self.fut.as_mut() {
91                return fut.as_mut().poll(cx);
92            } else if let Err(why) = self.start() {
93                return Poll::Ready(Err(why));
94            }
95        }
96    }
97}