ytmapi_rs/
client.rs

1//! This module contains the basic HTTP client used in this library.
2use crate::Result;
3use serde::Serialize;
4use std::borrow::Cow;
5
6/// Basic HTTP client using TLS wrapping a `reqwest::Client`,
7/// with the minimum required features to call YouTube Music queries.
8/// Clone is low cost, internals of `reqwest::Client` are wrapped in an Arc.
9#[derive(Debug, Clone)]
10pub struct Client {
11    inner: reqwest::Client,
12}
13
14impl Client {
15    /// Utilises reqwest's default tls choice for the enabled set of options.
16    pub fn new() -> Result<Self> {
17        let inner = reqwest::Client::builder().build()?;
18        Ok(Self { inner })
19    }
20    #[cfg(feature = "rustls-tls")]
21    #[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))]
22    /// Force the use of rustls-tls
23    pub fn new_rustls_tls() -> Result<Self> {
24        let inner = reqwest::Client::builder().use_rustls_tls().build()?;
25        Ok(Self { inner })
26    }
27    #[cfg(feature = "native-tls")]
28    #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))]
29    /// Force the use of native-tls
30    pub fn new_native_tls() -> Result<Self> {
31        let inner = reqwest::Client::builder().use_native_tls().build()?;
32        Ok(Self { inner })
33    }
34    /// Run a POST query, with url and headers.
35    /// Result is returned as a String.
36    pub async fn post_query<'a, I>(
37        &self,
38        url: impl AsRef<str>,
39        headers: impl IntoIterator<IntoIter = I>,
40        body_json: &(impl Serialize + ?Sized),
41        params: &(impl Serialize + ?Sized),
42    ) -> Result<String>
43    where
44        I: Iterator<Item = (&'a str, Cow<'a, str>)>,
45    {
46        let mut request_builder = self.inner.post(url.as_ref()).json(body_json).query(params);
47        for (header, value) in headers {
48            request_builder = request_builder.header(header, value.as_ref());
49        }
50        request_builder
51            .send()
52            .await?
53            .text()
54            .await
55            .map_err(Into::into)
56    }
57    /// Run a GET query, with url, key/value params and headers.
58    /// Result is returned as a String.
59    pub async fn get_query<'a, I>(
60        &self,
61        url: impl AsRef<str>,
62        headers: impl IntoIterator<IntoIter = I>,
63        params: &(impl Serialize + ?Sized),
64    ) -> Result<String>
65    where
66        I: Iterator<Item = (&'a str, Cow<'a, str>)>,
67    {
68        let mut request_builder = self.inner.get(url.as_ref()).query(params);
69        for (header, value) in headers {
70            request_builder = request_builder.header(header, value.as_ref());
71        }
72        request_builder
73            .send()
74            .await?
75            .text()
76            .await
77            .map_err(Into::into)
78    }
79}