duckduckgo_core/search/
client.rs1use std::path::PathBuf;
2use std::sync::Arc;
3
4use super::execute;
5use super::options::ClientOptions;
6use super::types::{SearchResponse, TimeFilter};
7use crate::Clock;
8use crate::Result;
9use crate::rate_limit::Limits;
10use crate::rate_limit::ProgressHook;
11use crate::region::Region;
12
13#[derive(Clone, Debug)]
14pub struct Client {
15 options: ClientOptions,
16}
17
18#[derive(Clone, Debug)]
19pub struct ClientBuilder {
20 options: ClientOptions,
21}
22
23#[derive(Clone, Debug)]
24pub struct SearchBuilder {
25 pub(crate) options: ClientOptions,
26 pub(crate) query: String,
27 pub(crate) page: usize,
28 pub(crate) time: Option<TimeFilter>,
29 pub(crate) sites: Vec<String>,
30}
31
32impl Client {
33 #[must_use]
34 pub fn builder() -> ClientBuilder {
35 ClientBuilder {
36 options: ClientOptions::default(),
37 }
38 }
39
40 #[must_use]
41 pub fn search(&self, query: impl Into<String>) -> SearchBuilder {
42 SearchBuilder {
43 options: self.options.clone(),
44 query: query.into(),
45 page: 1,
46 time: None,
47 sites: Vec::new(),
48 }
49 }
50}
51
52impl ClientBuilder {
53 pub fn region(mut self, region: Region) -> Self {
54 self.options.region = region;
55 self
56 }
57 pub fn num(mut self, num: usize) -> Self {
58 self.options.num = num;
59 self
60 }
61 pub fn safe(mut self, safe: bool) -> Self {
62 self.options.safe = safe;
63 self
64 }
65 pub fn timeout(mut self, seconds: u64) -> Self {
66 self.options.timeout = seconds;
67 self
68 }
69 pub fn proxy(mut self, proxy: Option<String>) -> Self {
70 self.options.proxy = proxy;
71 self
72 }
73 pub fn user_agent(mut self, value: Option<String>) -> Self {
74 self.options.user_agent = value;
75 self
76 }
77 pub fn retry(mut self, retry: u8) -> Self {
78 self.options.retry = retry;
79 self
80 }
81 pub fn no_wait(mut self, value: bool) -> Self {
82 self.options.no_wait = value;
83 self
84 }
85 pub fn no_rate_limit(mut self, value: bool) -> Self {
86 self.options.no_rate_limit = value;
87 self
88 }
89 pub fn state_dir(mut self, value: PathBuf) -> Self {
90 self.options.state_dir = value;
91 self
92 }
93 pub fn endpoint(mut self, value: String) -> Self {
94 self.options.endpoint = value;
95 self
96 }
97 pub fn limits(mut self, value: Limits) -> Self {
98 self.options.limits = value;
99 self
100 }
101 pub fn clock(mut self, value: Arc<dyn Clock>) -> Self {
102 self.options.clock = value;
103 self
104 }
105 #[must_use]
110 pub fn on_rate_limit_progress(mut self, hook: ProgressHook) -> Self {
111 self.options.progress_hook = Some(hook);
112 self
113 }
114 pub fn build(self) -> Result<Client> {
115 Ok(Client {
116 options: self.options,
117 })
118 }
119}
120
121impl SearchBuilder {
122 #[must_use]
123 pub fn page(mut self, page: usize) -> Self {
124 self.page = page;
125 self
126 }
127 #[must_use]
128 pub fn time(mut self, time: Option<TimeFilter>) -> Self {
129 self.time = time;
130 self
131 }
132 #[must_use]
133 pub fn site(mut self, site: String) -> Self {
134 self.sites.push(site);
135 self
136 }
137 pub async fn send(self) -> Result<SearchResponse> {
138 execute::execute(self).await
139 }
140}