Skip to content
This repository was archived by the owner on Jul 16, 2022. It is now read-only.

Commit 4178df7

Browse files
committed
async
1 parent b7cfefa commit 4178df7

File tree

4 files changed

+66
-50
lines changed

4 files changed

+66
-50
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ edition = "2018"
66

77
[dependencies]
88
dirs = "3.0"
9-
reqwest = { version = "0.10", features = ["blocking", "json"] }
9+
reqwest = { version = "0.10", features = ["json"] }
1010
serde = { version = "1.0", features = ["derive"] }
1111
serde_json = "1.0"
1212
structopt = "0.3"
13+
tokio = { version = "0.2", features = ["macros", "time"] }

src/api.rs

+41-31
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ trait RequestBuilder {
1515
fn auth(self, login: &Login) -> Self;
1616
}
1717

18-
impl RequestBuilder for reqwest::blocking::RequestBuilder {
18+
impl RequestBuilder for reqwest::RequestBuilder {
1919
fn auth(self, login: &Login) -> Self {
2020
match login {
2121
Login::OAuth(token) => self.header(AUTHORIZATION, format!("token {}", token)),
@@ -83,16 +83,16 @@ enum AccessTokenResponse {
8383
}
8484

8585
pub struct Client {
86-
client: reqwest::blocking::Client,
86+
client: reqwest::Client,
8787
}
8888

8989
impl Client {
9090
pub fn build() -> Result<Self> {
91-
let b = reqwest::blocking::Client::builder().user_agent("reqwest");
91+
let b = reqwest::Client::builder().user_agent("reqwest");
9292
Ok(Client { client: b.build()? })
9393
}
9494

95-
pub fn user(&self, login: &Login) -> Result<UserResponse> {
95+
pub async fn user(&self, login: &Login) -> Result<UserResponse> {
9696
let res = self
9797
.client
9898
.get("https://api.github.com/user")
@@ -101,18 +101,19 @@ impl Client {
101101
HeaderValue::from_static("application/vnd.github.v3+json"),
102102
)
103103
.auth(&login)
104-
.send()?;
104+
.send()
105+
.await?;
105106
if res.status().is_success() {
106-
Ok(res.json()?)
107+
Ok(res.json().await?)
107108
} else {
108109
Err(Error::new(ErrorKind::ApiWithStatus {
109110
status: res.status(),
110-
message: res.text()?,
111+
message: res.text().await?,
111112
}))
112113
}
113114
}
114115

115-
pub fn upload(
116+
pub async fn upload(
116117
&self,
117118
login: &Login,
118119
public: bool,
@@ -142,18 +143,23 @@ impl Client {
142143
.post("https://api.github.com/gists")
143144
.auth(&login)
144145
.json(&req)
145-
.send()?;
146+
.send()
147+
.await?;
146148
if res.status().is_success() {
147-
Ok(res.json::<GistResponse>()?)
149+
Ok(res.json::<GistResponse>().await?)
148150
} else {
149151
Err(Error::new(ErrorKind::ApiWithStatus {
150152
status: res.status(),
151-
message: res.text()?,
153+
message: res.text().await?,
152154
}))
153155
}
154156
}
155157

156-
pub fn list(&self, login: Option<&Login>, username: Option<&str>) -> Result<ListResponse> {
158+
pub async fn list(
159+
&self,
160+
login: Option<&Login>,
161+
username: Option<&str>,
162+
) -> Result<ListResponse> {
157163
let mut builder = if let Some(username) = username {
158164
self.client
159165
.get(&format!("https://api.github.com/users/{}/gists", username))
@@ -165,50 +171,52 @@ impl Client {
165171
builder = builder.auth(&login);
166172
}
167173

168-
let res = builder.send()?;
174+
let res = builder.send().await?;
169175
if res.status().is_success() {
170-
Ok(res.json::<ListResponse>()?)
176+
Ok(res.json::<ListResponse>().await?)
171177
} else {
172178
Err(Error::new(ErrorKind::ApiWithStatus {
173179
status: res.status(),
174-
message: res.text()?,
180+
message: res.text().await?,
175181
}))
176182
}
177183
}
178184

179-
pub fn list_starred(&self, login: &Login) -> Result<ListResponse> {
185+
pub async fn list_starred(&self, login: &Login) -> Result<ListResponse> {
180186
let res = self
181187
.client
182188
.get("https://api.github.com/gists/starred")
183189
.auth(&login)
184-
.send()?;
190+
.send()
191+
.await?;
185192
if res.status().is_success() {
186-
Ok(res.json::<ListResponse>()?)
193+
Ok(res.json::<ListResponse>().await?)
187194
} else {
188195
Err(Error::new(ErrorKind::ApiWithStatus {
189196
status: res.status(),
190-
message: res.text()?,
197+
message: res.text().await?,
191198
}))
192199
}
193200
}
194201

195-
pub fn delete(&self, login: &Login, id: &str) -> Result<()> {
202+
pub async fn delete(&self, login: &Login, id: &str) -> Result<()> {
196203
let res = self
197204
.client
198205
.delete(&format!("https://api.github.com/gists/{}", id))
199206
.auth(&login)
200-
.send()?;
207+
.send()
208+
.await?;
201209
if res.status().is_success() {
202210
Ok(())
203211
} else {
204212
Err(Error::new(ErrorKind::ApiWithStatus {
205213
status: res.status(),
206-
message: res.text()?,
214+
message: res.text().await?,
207215
}))
208216
}
209217
}
210218

211-
pub fn request_verification_code(
219+
pub async fn request_verification_code(
212220
&self,
213221
client_id: &str,
214222
scope: &str,
@@ -222,18 +230,19 @@ impl Client {
222230
.post("https://github.com/login/device/code")
223231
.header(ACCEPT, HeaderValue::from_static("application/json"))
224232
.json(&req)
225-
.send()?;
233+
.send()
234+
.await?;
226235
if res.status().is_success() {
227-
Ok(res.json()?)
236+
Ok(res.json().await?)
228237
} else {
229238
Err(Error::new(ErrorKind::ApiWithStatus {
230239
status: res.status(),
231-
message: res.text()?,
240+
message: res.text().await?,
232241
}))
233242
}
234243
}
235244

236-
pub fn request_access_token(
245+
pub async fn request_access_token(
237246
&self,
238247
client_id: &str,
239248
device_code: &str,
@@ -245,17 +254,18 @@ impl Client {
245254
grant_type: "urn:ietf:params:oauth:grant-type:device_code".to_owned(),
246255
};
247256
loop {
248-
std::thread::sleep(Duration::from_secs(interval));
257+
tokio::time::delay_for(Duration::from_secs(interval)).await;
249258

250259
let res = self
251260
.client
252261
.post("https://github.com/login/oauth/access_token")
253262
.header(ACCEPT, HeaderValue::from_static("application/json"))
254263
.json(&req)
255-
.send()?;
264+
.send()
265+
.await?;
256266

257267
if res.status().is_success() {
258-
match res.json::<AccessTokenResponse>()? {
268+
match res.json::<AccessTokenResponse>().await? {
259269
AccessTokenResponse::AccessToken { access_token } => {
260270
return Ok(Login::OAuth(access_token))
261271
}
@@ -267,7 +277,7 @@ impl Client {
267277
} else {
268278
return Err(Error::new(ErrorKind::ApiWithStatus {
269279
status: res.status(),
270-
message: res.text()?,
280+
message: res.text().await?,
271281
}));
272282
}
273283
}

src/app.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,30 @@ use crate::api;
44
use crate::config;
55
use crate::error::Result;
66

7-
pub fn upload(
7+
pub async fn upload(
88
login: &config::Login,
99
secret: bool,
1010
description: Option<&str>,
1111
files: &[PathBuf],
1212
) -> Result<()> {
1313
let client = api::Client::build()?;
14-
let res = client.upload(&login, !secret, description, files)?;
14+
let res = client.upload(&login, !secret, description, files).await?;
1515

1616
println!("{}", res.html_url);
1717

1818
Ok(())
1919
}
2020

21-
pub fn list(login: Option<&config::Login>, username: Option<&str>) -> Result<()> {
21+
pub async fn list(login: Option<&config::Login>, username: Option<&str>) -> Result<()> {
2222
let client = api::Client::build()?;
23-
let r = client.list(login, username)?;
23+
let r = client.list(login, username).await?;
2424
list_gists(&r);
2525
Ok(())
2626
}
2727

28-
pub fn list_starred(login: &config::Login) -> Result<()> {
28+
pub async fn list_starred(login: &config::Login) -> Result<()> {
2929
let client = api::Client::build()?;
30-
let r = client.list_starred(login)?;
30+
let r = client.list_starred(login).await?;
3131
list_gists(&r);
3232
Ok(())
3333
}
@@ -42,28 +42,30 @@ fn list_gists(gists: &[api::GistResponse]) {
4242
}
4343
}
4444

45-
pub fn delete(login: &config::Login, id: &[String]) -> Result<()> {
45+
pub async fn delete(login: &config::Login, id: &[String]) -> Result<()> {
4646
let client = api::Client::build()?;
4747
for i in id.into_iter() {
48-
client.delete(login, &i)?;
48+
client.delete(login, &i).await?;
4949
println!("{}", i);
5050
}
5151
println!("Success!");
5252
Ok(())
5353
}
5454

55-
pub fn login(client_id: &str) -> Result<()> {
55+
pub async fn login(client_id: &str) -> Result<()> {
5656
let client = api::Client::build()?;
5757

58-
let vc = client.request_verification_code(client_id, "gist")?;
58+
let vc = client.request_verification_code(client_id, "gist").await?;
5959

6060
println!("open {} and enter '{}'", vc.verification_uri, vc.user_code);
6161

62-
let login = client.request_access_token(client_id, &vc.device_code, vc.interval)?;
62+
let login = client
63+
.request_access_token(client_id, &vc.device_code, vc.interval)
64+
.await?;
6365

6466
println!("{:#?}", login);
6567

66-
let u = client.user(&login)?;
68+
let u = client.user(&login).await?;
6769
println!("{:#?}", u);
6870

6971
let mut cfg = config::load_config()?;

src/bin/gist.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,31 @@ struct Delete {
8181
id: Vec<String>,
8282
}
8383

84-
fn main() -> Result<()> {
84+
#[tokio::main]
85+
async fn main() -> Result<()> {
8586
let args = Args::from_args();
8687

8788
match args.command {
88-
Subcommand::Login(opt) => gist::app::login(&opt.client_id),
89+
Subcommand::Login(opt) => gist::app::login(&opt.client_id).await?,
8990
Subcommand::Upload(u) => {
9091
let l = select_account(args.account)?;
91-
gist::app::upload(&l, u.secret, u.description.as_deref(), &u.files)
92+
gist::app::upload(&l, u.secret, u.description.as_deref(), &u.files).await?;
9293
}
9394
Subcommand::List(opt) => {
9495
let l = select_account(args.account);
9596
if opt.starred {
96-
gist::app::list_starred(&l?)
97+
gist::app::list_starred(&l?).await?;
9798
} else {
98-
gist::app::list(l.ok().as_ref(), opt.username.as_deref())
99+
gist::app::list(l.ok().as_ref(), opt.username.as_deref()).await?;
99100
}
100101
}
101102
Subcommand::Delete(opt) => {
102103
let l = select_account(args.account)?;
103-
gist::app::delete(&l, &opt.id)
104+
gist::app::delete(&l, &opt.id).await?;
104105
}
105106
}
107+
108+
Ok(())
106109
}
107110

108111
fn select_account(account: Account) -> Result<gist::config::Login> {

0 commit comments

Comments
 (0)