Skip to content

Commit b5f988f

Browse files
Merge #246
246: modules r=Emilgardis a=Emilgardis - add doc_auto_cfg - split up helix into more modules - move endpoints to another module Co-authored-by: Emil Gardström <emil.gardstrom@gmail.com>
2 parents c259b19 + fd92dfb commit b5f988f

File tree

96 files changed

+1414
-1384
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1414
-1384
lines changed

src/helix/client.rs

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
//! Client for Helix endpoints
2+
use super::*;
3+
4+
pub(crate) mod client_ext;
5+
#[cfg(feature = "unsupported")]
6+
mod custom;
7+
8+
#[cfg(feature = "client")]
9+
impl<C: crate::HttpClient<'static> + crate::client::ClientDefault<'static>> Default
10+
for HelixClient<'static, C>
11+
{
12+
fn default() -> Self { Self::new() }
13+
}
14+
15+
/// Client for Helix or the [New Twitch API](https://dev.twitch.tv/docs/api)
16+
///
17+
/// Provides [`HelixClient::req_get`] for requesting endpoints which uses [GET method][RequestGet].
18+
///
19+
///
20+
/// Most [clients][crate::HttpClient] will be able to use the `'static` lifetime
21+
///
22+
/// ```rust,no_run
23+
/// # use twitch_api2::{HelixClient}; pub mod reqwest {pub type Client = twitch_api2::client::DummyHttpClient;}
24+
/// pub struct MyStruct {
25+
/// twitch: HelixClient<'static, reqwest::Client>,
26+
/// token: twitch_oauth2::AppAccessToken,
27+
/// }
28+
/// // etc
29+
/// ```
30+
///
31+
/// See [`HttpClient`][crate::HttpClient] for implemented http clients, you can also define your own if needed.
32+
///
33+
/// # Examples
34+
///
35+
/// Get a [user](users::User) from their login name.
36+
///
37+
/// ```rust,no_run
38+
/// # #[tokio::main]
39+
/// # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
40+
/// # pub mod reqwest {pub type Client = twitch_api2::client::DummyHttpClient;}
41+
/// let client: HelixClient<'static, reqwest::Client> = HelixClient::default();
42+
/// # let token = twitch_oauth2::AccessToken::new("validtoken".to_string());
43+
/// # let token = twitch_oauth2::UserToken::from_existing(&client, token, None, None).await?;
44+
/// use twitch_api2::helix::{users::User, HelixClient};
45+
/// let user: Option<User> = client
46+
/// .get_user_from_login("justintv".to_string(), &token)
47+
/// .await
48+
/// .unwrap();
49+
/// # Ok(()) }
50+
/// ```
51+
#[derive(Clone)]
52+
#[cfg(all(feature = "client", feature = "helix"))] // this is needed due to a bug?
53+
pub struct HelixClient<'a, C>
54+
where C: crate::HttpClient<'a> {
55+
pub(crate) client: C,
56+
pub(crate) _pd: std::marker::PhantomData<&'a ()>, // TODO: Implement rate limiter...
57+
}
58+
59+
#[cfg(feature = "client")]
60+
impl<'a, C: crate::HttpClient<'a>> HelixClient<'a, C> {
61+
/// Create a new client with an existing client
62+
pub fn with_client(client: C) -> HelixClient<'a, C> {
63+
HelixClient {
64+
client,
65+
_pd: std::marker::PhantomData::default(),
66+
}
67+
}
68+
69+
/// Create a new [`HelixClient`] with a default [`HttpClient`][crate::HttpClient]
70+
pub fn new() -> HelixClient<'a, C>
71+
where C: crate::client::ClientDefault<'a> {
72+
let client = C::default_client();
73+
HelixClient::with_client(client)
74+
}
75+
76+
/// Retrieve a clone of the [`HttpClient`][crate::HttpClient] inside this [`HelixClient`]
77+
pub fn clone_client(&self) -> C
78+
where C: Clone {
79+
self.client.clone()
80+
}
81+
82+
/// Retrieve a reference of the [`HttpClient`][crate::HttpClient] inside this [`HelixClient`]
83+
pub fn get_client(&self) -> &C { &self.client }
84+
85+
/// Request on a valid [`RequestGet`] endpoint
86+
///
87+
/// ```rust,no_run
88+
/// # #[tokio::main]
89+
/// # async fn main() {
90+
/// # use twitch_api2::helix::{HelixClient, channels};
91+
/// # let token = Box::new(twitch_oauth2::UserToken::from_existing_unchecked(
92+
/// # twitch_oauth2::AccessToken::new("totallyvalidtoken".to_string()), None,
93+
/// # twitch_oauth2::ClientId::new("validclientid".to_string()), None, "justintv".to_string(), "1337".to_string(), None, None));
94+
/// let req = channels::GetChannelInformationRequest::builder().broadcaster_id("123456").build();
95+
/// let client = HelixClient::new();
96+
/// # let _: &HelixClient<twitch_api2::DummyHttpClient> = &client;
97+
///
98+
/// let response = client.req_get(req, &token).await;
99+
/// # }
100+
/// # // fn main() {run()}
101+
/// ```
102+
pub async fn req_get<R, D, T>(
103+
&'a self,
104+
request: R,
105+
token: &T,
106+
) -> Result<Response<R, D>, ClientRequestError<<C as crate::HttpClient<'a>>::Error>>
107+
where
108+
R: Request<Response = D> + Request + RequestGet,
109+
D: serde::de::DeserializeOwned + PartialEq,
110+
T: TwitchToken + ?Sized,
111+
C: Send,
112+
{
113+
let req = request.create_request(token.token().secret(), token.client_id().as_str())?;
114+
let uri = req.uri().clone();
115+
let response = self
116+
.client
117+
.req(req)
118+
.await
119+
.map_err(ClientRequestError::RequestError)?;
120+
<R>::parse_response(Some(request), &uri, response).map_err(Into::into)
121+
}
122+
123+
/// Request on a valid [`RequestPost`] endpoint
124+
pub async fn req_post<R, B, D, T>(
125+
&'a self,
126+
request: R,
127+
body: B,
128+
token: &T,
129+
) -> Result<Response<R, D>, ClientRequestError<<C as crate::HttpClient<'a>>::Error>>
130+
where
131+
R: Request<Response = D> + Request + RequestPost<Body = B>,
132+
B: HelixRequestBody,
133+
D: serde::de::DeserializeOwned + PartialEq,
134+
T: TwitchToken + ?Sized,
135+
{
136+
let req =
137+
request.create_request(body, token.token().secret(), token.client_id().as_str())?;
138+
let uri = req.uri().clone();
139+
let response = self
140+
.client
141+
.req(req)
142+
.await
143+
.map_err(ClientRequestError::RequestError)?;
144+
<R>::parse_response(Some(request), &uri, response).map_err(Into::into)
145+
}
146+
147+
/// Request on a valid [`RequestPatch`] endpoint
148+
pub async fn req_patch<R, B, D, T>(
149+
&'a self,
150+
request: R,
151+
body: B,
152+
token: &T,
153+
) -> Result<Response<R, D>, ClientRequestError<<C as crate::HttpClient<'a>>::Error>>
154+
where
155+
R: Request<Response = D> + Request + RequestPatch<Body = B>,
156+
B: HelixRequestBody,
157+
D: serde::de::DeserializeOwned + PartialEq,
158+
T: TwitchToken + ?Sized,
159+
{
160+
let req =
161+
request.create_request(body, token.token().secret(), token.client_id().as_str())?;
162+
let uri = req.uri().clone();
163+
let response = self
164+
.client
165+
.req(req)
166+
.await
167+
.map_err(ClientRequestError::RequestError)?;
168+
<R>::parse_response(Some(request), &uri, response).map_err(Into::into)
169+
}
170+
171+
/// Request on a valid [`RequestDelete`] endpoint
172+
pub async fn req_delete<R, D, T>(
173+
&'a self,
174+
request: R,
175+
token: &T,
176+
) -> Result<Response<R, D>, ClientRequestError<<C as crate::HttpClient<'a>>::Error>>
177+
where
178+
R: Request<Response = D> + Request + RequestDelete,
179+
D: serde::de::DeserializeOwned + PartialEq,
180+
T: TwitchToken + ?Sized,
181+
{
182+
let req = request.create_request(token.token().secret(), token.client_id().as_str())?;
183+
let uri = req.uri().clone();
184+
let response = self
185+
.client
186+
.req(req)
187+
.await
188+
.map_err(ClientRequestError::RequestError)?;
189+
<R>::parse_response(Some(request), &uri, response).map_err(Into::into)
190+
}
191+
192+
/// Request on a valid [`RequestPut`] endpoint
193+
pub async fn req_put<R, B, D, T>(
194+
&'a self,
195+
request: R,
196+
body: B,
197+
token: &T,
198+
) -> Result<Response<R, D>, ClientRequestError<<C as crate::HttpClient<'a>>::Error>>
199+
where
200+
R: Request<Response = D> + Request + RequestPut<Body = B>,
201+
B: HelixRequestBody,
202+
D: serde::de::DeserializeOwned + PartialEq,
203+
T: TwitchToken + ?Sized,
204+
{
205+
let req =
206+
request.create_request(body, token.token().secret(), token.client_id().as_str())?;
207+
let uri = req.uri().clone();
208+
let response = self
209+
.client
210+
.req(req)
211+
.await
212+
.map_err(ClientRequestError::RequestError)?;
213+
<R>::parse_response(Some(request), &uri, response).map_err(Into::into)
214+
}
215+
}
File renamed without changes.

0 commit comments

Comments
 (0)