-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub_accounts.rs
More file actions
82 lines (73 loc) · 2.46 KB
/
github_accounts.rs
File metadata and controls
82 lines (73 loc) · 2.46 KB
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
use std::collections::BTreeMap;
use anyhow::Context;
use email_address::EmailAddress;
use serde::{Deserialize, Serialize};
use crate::{
Error,
newtypes::{GithubLogin, Region, new_case_insensitive_email_address},
sheets::{Sheet, SheetsClient, cell_string},
};
// TODO: Replace this with a serde implementation from a Google Sheet.
pub(crate) async fn get_trainees(
client: SheetsClient,
sheet_id: &str,
) -> Result<BTreeMap<GithubLogin, Trainee>, Error> {
const EXPECTED_SHEET_NAME: &str = "Form responses 1";
let data = client.get(sheet_id).await.map_err(|err| {
err.with_context(|| {
format!(
"Failed to get trainees github accounts sheet with id {}",
sheet_id
)
})
})?;
let sheet = data.get(EXPECTED_SHEET_NAME);
if let Some(sheet) = sheet {
let data = trainees_from_sheet(&sheet).map_err(|err| {
err.with_context(|| {
format!("Failed to read trainees from sheet {}", EXPECTED_SHEET_NAME,)
})
})?;
Ok(data)
} else {
Err(Error::Fatal(anyhow::anyhow!(
"Didn't find sheet '{}' in trainee GitHub sheet with id {}",
EXPECTED_SHEET_NAME,
sheet_id
)))
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Trainee {
pub name: String,
pub region: Region,
pub github_login: GithubLogin,
pub email: EmailAddress,
}
fn trainees_from_sheet(sheet: &Sheet) -> Result<BTreeMap<GithubLogin, Trainee>, Error> {
let mut trainees = BTreeMap::new();
for (row_index, cells) in sheet.rows.iter().enumerate() {
if row_index == 0 {
continue;
}
if cells.len() < 5 {
return Err(Error::Fatal(anyhow::anyhow!(
"Reading trainee data from Google Sheets API, row {} didn't have at least 5 columns",
row_index
)));
}
let github_login = GithubLogin::from(cell_string(&cells[3]).trim().to_owned());
let email = cell_string(&cells[4]);
trainees.insert(
github_login.clone(),
Trainee {
name: cell_string(&cells[1]),
region: Region(cell_string(&cells[2])),
github_login,
email: new_case_insensitive_email_address(&email)
.with_context(|| format!("Failed to parse trainee email {}", email))?,
},
);
}
Ok(trainees)
}