invidious/structs/global/
methods.rs

1#![allow(unreachable_code)]
2#![allow(unreachable_patterns)]
3
4use std::{future::Future, pin::Pin};
5
6/// Type of a custom sync fetch function
7pub type MethodSyncCustom = Box<dyn Fn(&str) -> MethodReturn>;
8/// Type of a custom async fetch function
9pub type AsyncMethodCustom =
10    Box<dyn Fn(String) -> Pin<Box<dyn Future<Output = MethodReturn> + Send>> + Send + Sync>;
11/// Return type of fetch functions
12pub type MethodReturn = Result<String, Box<dyn std::error::Error>>;
13
14/// Request methods for `ClientSync`.
15///
16/// ## Binary build times
17///
18/// Build times are tested on my local Arch Linux machine, with `--release` flag..
19///
20/// |Feature|Time(s)|Crate|
21/// |---|---|---|
22/// |None|6.9|-|
23/// |httpreq_sync (default)|11.4|[http_req](https://crates.io/crates/http_req)|
24/// |minreq_sync|11.6|[minreq](https://crates.io/crates/minreq)|
25/// |ureq_sync|13.1|[ureq](https://crates.io/crates/ureq)|
26/// |reqwest_sync|18.0|[reqwest](https://crates.io/crates/reqwest)|
27/// |isahc_sync|22.6|[isahc](https://crates.io/crates/isahc)|
28/// |minreq_http_sync|10.1|[minreq](https://crates.io/crates/minreq)|
29#[cfg(feature = "sync")]
30#[derive(Clone, Copy)]
31pub enum MethodSync {
32    /// Default - Quickest compile time, but part of the fetching function is written by me, so it might be erroneous.
33    #[cfg(feature = "httpreq_sync")]
34    HttpReq,
35    /// Second quickest in compile time, it comes with the fetching function, so it's less likely to fail.
36    #[cfg(feature = "minreq_sync")]
37    MinReq,
38    /// It's just another very lightweight http client I've found.
39    #[cfg(feature = "ureq_sync")]
40    Ureq,
41    /// Everyone knows about reqwest.
42    #[cfg(feature = "reqwest_sync")]
43    Reqwest,
44    /// Just here because it also offers an async API.
45    #[cfg(feature = "isahc_sync")]
46    Isahc,
47    /// Unsafe - http only, use at your own risk.
48    #[cfg(feature = "minreq_http_sync")]
49    MinReqHttp,
50}
51
52#[cfg(feature = "sync")]
53impl Default for MethodSync {
54    /// Returns the first enabled method. Panics if no methods are enabled in features.
55    ///
56    /// The ordering is as follows:
57    /// 1. httpreq_sync
58    /// 2. minreq_sync
59    /// 3. ureq_sync
60    /// 4. reqwest_sync
61    /// 5. isahc_sync
62    /// 6. minreq_http_sync
63    fn default() -> Self {
64        #[cfg(feature = "httpreq_sync")]
65        return MethodSync::HttpReq;
66        #[cfg(feature = "ureq_sync")]
67        return MethodSync::Ureq;
68        #[cfg(feature = "minreq_sync")]
69        return MethodSync::MinReq;
70        #[cfg(feature = "reqwest_sync")]
71        return MethodSync::Reqwest;
72        #[cfg(feature = "isahc_sync")]
73        return MethodSync::Isahc;
74        #[cfg(feature = "minreq_http_sync")]
75        return MethodSync::MinReqHttp;
76        panic!("No method selected");
77    }
78}
79
80#[cfg(feature = "sync")]
81impl MethodSync {
82    /// Fetches the result string from a URL using the selected method.
83    pub fn fetch(&self, url: &str) -> Result<String, Box<dyn std::error::Error>> {
84        Ok(match self {
85            #[cfg(feature = "reqwest_sync")]
86            MethodSync::Reqwest => reqwest::blocking::get(url)?.text()?,
87            #[cfg(feature = "ureq_sync")]
88            MethodSync::Ureq => ureq::get(url).call()?.into_string()?,
89            #[cfg(feature = "httpreq_sync")]
90            MethodSync::HttpReq => String::from_utf8(crate::functions::httpreq_get(url)?)?,
91            #[cfg(feature = "minreq_http_sync")]
92            MethodSync::MinReqHttp => String::from_utf8(minreq::get(url).send()?.into_bytes())?,
93            #[cfg(feature = "minreq_sync")]
94            MethodSync::MinReq => String::from_utf8(minreq::get(url).send()?.into_bytes())?,
95            #[cfg(feature = "isahc_sync")]
96            MethodSync::Isahc => {
97                use isahc::ReadResponseExt;
98                isahc::get(url)?.text()?
99            }
100            _ => panic!("No method selected"),
101        })
102    }
103}
104
105/// Request methods for `ClientAsync`.
106///
107/// ## Binary build times
108///
109/// Build times are tested on my local Arch Linux machine, with `--release` flag..
110///
111/// |Feature|Time(s)|Crate|
112/// |---|---|---|
113/// |None|6.9|-|
114/// |reqwest_async|17.7|[reqwest](https://crates.io/crates/reqwest)|
115/// |isahc_async|20.4|[isahc](https://crates.io/crates/isahc)|
116#[cfg(feature = "async")]
117#[derive(Clone, Copy)]
118pub enum MethodAsync {
119    /// Everyone knows about reqwest.
120    #[cfg(feature = "reqwest_async")]
121    Reqwest,
122    /// Supports runtime other than tokio.
123    #[cfg(feature = "isahc_async")]
124    Isahc,
125}
126
127#[cfg(feature = "async")]
128impl Default for MethodAsync {
129    /// Returns the first enabled method. Panics if no methods are enabled in features.
130    ///
131    /// The ordering is as follows:
132    /// 1. reqwest_async
133    /// 2. isahc_async
134    fn default() -> Self {
135        #[cfg(feature = "reqwest_async")]
136        return MethodAsync::Reqwest;
137        #[cfg(feature = "isahc_async")]
138        return MethodAsync::Isahc;
139        panic!("No method selected");
140    }
141}
142
143#[cfg(feature = "async")]
144impl MethodAsync {
145    /// Fetches the result string from a URL using the selected method.
146    pub async fn fetch(&self, url: &str) -> Result<String, Box<dyn std::error::Error>> {
147        Ok(match self {
148            #[cfg(feature = "reqwest_async")]
149            MethodAsync::Reqwest => reqwest::get(url).await?.text().await?,
150            #[cfg(feature = "isahc_async")]
151            MethodAsync::Isahc => {
152                use isahc::AsyncReadResponseExt;
153                isahc::get_async(url).await?.text().await?
154            }
155        })
156    }
157}