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
|
use crate::prelude::*;
pub fn oauth_config(
client_id: &str,
client_secret: &str,
redirect_url: &url::Url,
) -> crate::oauth::Config {
crate::oauth::Config::new(
client_id.to_string(),
client_secret.to_string(),
url::Url::parse("https://www.recurse.com/oauth/authorize").unwrap(),
url::Url::parse("https://www.recurse.com/oauth/token").unwrap(),
redirect_url.clone(),
)
}
pub fn get_username(
access_token: &str,
) -> Box<dyn futures::Future<Item = String, Error = Error> + Send> {
let fut = reqwest::r#async::Client::new()
.get("https://www.recurse.com/api/v1/profiles/me")
.bearer_auth(access_token)
.send()
.context(crate::error::GetRecurseCenterProfile)
.and_then(|mut res| res.json().context(crate::error::ParseJson))
.map(|user: User| user.name());
Box::new(fut)
}
#[derive(serde::Deserialize)]
struct User {
name: String,
stints: Vec<Stint>,
}
#[derive(serde::Deserialize)]
struct Stint {
batch: Option<Batch>,
start_date: String,
}
#[derive(serde::Deserialize)]
struct Batch {
short_name: String,
}
impl User {
fn name(&self) -> String {
let latest_stint =
self.stints.iter().max_by_key(|s| &s.start_date).unwrap();
if let Some(batch) = &latest_stint.batch {
format!("{} ({})", self.name, batch.short_name)
} else {
self.name.to_string()
}
}
}
|