1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
//! Bridged support for the `hyper` HTTP client.
use hyper::client::{Body, Client as HyperClient};
use hyper::header::ContentType;
use serde_json;
use serde_urlencoded;
use ::constants::BASE_TOKEN_URI;
use ::model::{
AccessTokenExchangeRequest,
AccessTokenResponse,
RefreshTokenRequest,
};
use ::Result;
/// A trait used that implements methods for interacting with Discord's OAuth2
/// API on Hyper's client.
///
/// # Examples
///
/// Bringing in the trait and creating a client. Since the trait is in scope,
/// the instance of hyper's Client will have those methods available:
///
/// ```rust,no_run
/// extern crate hyper;
/// extern crate serenity_oauth;
///
/// # fn main() {
/// use hyper::Client;
///
/// let client = Client::new();
///
/// // At this point, the methods defined by the trait are not in scope. By
/// // using the trait, they will be.
/// use serenity_oauth::DiscordOAuthHyperRequester;
///
/// // The methods defined by `DiscordOAuthHyperRequester` are now in scope and
/// // implemented on the instance of hyper's `Client`.
/// # }
/// ```
///
/// For examples of how to use the trait with the Client, refer to the trait's
/// methods.
pub trait DiscordOAuthHyperRequester {
/// Exchanges a code for the user's access token.
///
/// # Examples
///
/// Exchange a code for an access token:
///
/// ```rust,no_run
/// extern crate hyper;
/// extern crate serenity_oauth;
///
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
/// use hyper::Client;
/// use serenity_oauth::model::AccessTokenExchangeRequest;
/// use serenity_oauth::DiscordOAuthHyperRequester;
///
/// let request_data = AccessTokenExchangeRequest::new(
/// 249608697955745802,
/// "dd99opUAgs7SQEtk2kdRrTMU5zagR2a4",
/// "user code here",
/// "https://myapplication.website",
/// );
///
/// let client = Client::new();
/// let response = client.exchange_code(&request_data)?;
///
/// println!("Access token: {}", response.access_token);
/// # Ok(())
/// # }
/// #
/// # fn main() {
/// # try_main().unwrap();
/// # }
/// ```
fn exchange_code(&self, request: &AccessTokenExchangeRequest)
-> Result<AccessTokenResponse>;
/// Exchanges a refresh token, returning a new refresh token and fresh
/// access token.
///
/// # Examples
///
/// Exchange a refresh token:
///
/// ```rust,no_run
/// extern crate hyper;
/// extern crate serenity_oauth;
///
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
/// use hyper::Client;
/// use serenity_oauth::model::RefreshTokenRequest;
/// use serenity_oauth::DiscordOAuthHyperRequester;
///
/// let request_data = RefreshTokenRequest::new(
/// 249608697955745802,
/// "dd99opUAgs7SQEtk2kdRrTMU5zagR2a4",
/// "user code here",
/// "https://myapplication.website",
/// );
///
/// let client = Client::new();
/// let response = client.exchange_refresh_token(&request_data)?;
///
/// println!("Fresh access token: {}", response.access_token);
/// # Ok(())
/// # }
/// #
/// # fn main() {
/// # try_main().unwrap();
/// # }
/// ```
fn exchange_refresh_token(&self, request: &RefreshTokenRequest)
-> Result<AccessTokenResponse>;
}
impl DiscordOAuthHyperRequester for HyperClient {
fn exchange_code(&self, request: &AccessTokenExchangeRequest)
-> Result<AccessTokenResponse> {
let body = serde_urlencoded::to_string(request)?;
let response = self.post(BASE_TOKEN_URI)
.header(ContentType::form_url_encoded())
.body(Body::BufBody(body.as_bytes(), body.len()))
.send()?;
serde_json::from_reader(response).map_err(From::from)
}
fn exchange_refresh_token(&self, request: &RefreshTokenRequest)
-> Result<AccessTokenResponse> {
let body = serde_json::to_string(request)?;
let response = self.post(BASE_TOKEN_URI)
.body(Body::BufBody(body.as_bytes(), body.len()))
.send()?;
serde_json::from_reader(response).map_err(From::from)
}
}
|