everything here is to taste, but wanted to throw a few rust idioms in that help with some of the indentation drift, if we like them!
+65
-78
shared/src/advent/challenges/day_one.rs
+65
-78
shared/src/advent/challenges/day_one.rs
···
2
2
use crate::advent::day::Day;
3
3
use crate::advent::{AdventChallenge, AdventError, ChallengeCheckResponse};
4
4
use crate::atrium::safe_check_unknown_record_parse;
5
5
+
use crate::lexicons::codes::advent;
5
6
use async_trait::async_trait;
6
7
use atrium_api::types::Collection;
7
8
use sqlx::PgPool;
···
30
31
did: String,
31
32
_verification_code: Option<String>,
32
33
) -> Result<ChallengeCheckResponse, AdventError> {
33
33
-
match &self.oauth_client {
34
34
-
None => Err(AdventError::ShouldNotHappen(
34
34
+
let client = self
35
35
+
.oauth_client
36
36
+
.as_ref()
37
37
+
.ok_or(AdventError::ShouldNotHappen(
35
38
"No oauth client. This should not happen".to_string(),
36
36
-
)),
37
37
-
Some(client) => {
38
38
-
match client
39
39
-
.api
40
40
-
.com
41
41
-
.atproto
42
42
-
.repo
43
43
-
.get_record(
44
44
-
atrium_api::com::atproto::repo::get_record::ParametersData {
45
45
-
cid: None,
46
46
-
collection: crate::lexicons::codes::advent::challenge::Day::NSID
47
47
-
.parse()
48
48
-
.unwrap(),
49
49
-
repo: did.parse().unwrap(),
50
50
-
rkey: "1".parse().unwrap(),
51
51
-
}
52
52
-
.into(),
53
53
-
)
54
54
-
.await
55
55
-
{
56
56
-
Ok(record) => {
57
57
-
//TODO trouble, and make it double
58
58
-
let challenge = self.get_days_challenge(did.clone()).await?;
59
59
-
60
60
-
match challenge {
61
61
-
None => {
62
62
-
log::error!(
63
63
-
"Could not find a challenge record for day: {} for the user: {}",
64
64
-
self.day(),
65
65
-
did.clone()
66
66
-
);
67
67
-
Err(AdventError::ShouldNotHappen(
68
68
-
"Could not find a challenge record".to_string(),
69
69
-
))
70
70
-
}
71
71
-
Some(challenge) => {
72
72
-
let parse_record_result =
73
73
-
safe_check_unknown_record_parse::<
74
74
-
crate::lexicons::codes::advent::challenge::day::RecordData,
75
75
-
>(record.value.clone());
39
39
+
))?;
76
40
77
77
-
match parse_record_result {
78
78
-
Ok(record_data) => {
79
79
-
match record_data.part_one
80
80
-
== challenge
81
81
-
.verification_code_one
82
82
-
.unwrap_or("".to_string())
83
83
-
{
84
84
-
true => Ok(ChallengeCheckResponse::Correct),
85
85
-
false => {
86
86
-
Ok(ChallengeCheckResponse::Incorrect(format!(
87
87
-
"The code {} is incorrect",
88
88
-
record_data.part_one
89
89
-
)))
90
90
-
}
91
91
-
}
92
92
-
}
93
93
-
Err(err) => {
94
94
-
log::error!("Error parsing record: {}", err);
95
95
-
Ok(ChallengeCheckResponse::Incorrect(format!(
96
96
-
"There is a record at the correct location, but it does not seem like it is correct. Try again:\n{err}"
97
97
-
)))
98
98
-
}
99
99
-
}
100
100
-
}
101
101
-
}
102
102
-
}
103
103
-
Err(err) => {
104
104
-
log::error!("Error getting record: {}", err);
105
105
-
Ok(ChallengeCheckResponse::Incorrect("Does not appear to be a record in your repo in the collection codes.advent.challenge.day with the record key of 1".to_string()))
106
106
-
}
41
41
+
let record_res = client
42
42
+
.api
43
43
+
.com
44
44
+
.atproto
45
45
+
.repo
46
46
+
.get_record(
47
47
+
atrium_api::com::atproto::repo::get_record::ParametersData {
48
48
+
cid: None,
49
49
+
collection: advent::challenge::Day::NSID.parse().unwrap(),
50
50
+
repo: did.parse().unwrap(),
51
51
+
rkey: "1".parse().unwrap(),
107
52
}
53
53
+
.into(),
54
54
+
)
55
55
+
.await;
56
56
+
57
57
+
let record = match record_res {
58
58
+
Ok(r) => r,
59
59
+
Err(e) => {
60
60
+
log::error!("Error getting record: {}", e);
61
61
+
return Ok(ChallengeCheckResponse::Incorrect("Does not appear to be a record in your repo in the collection codes.advent.challenge.day with the record key of 1".to_string()));
108
62
}
109
109
-
}
63
63
+
};
64
64
+
65
65
+
let Some(challenge) = self.get_days_challenge(&did).await? else {
66
66
+
log::error!("Could not find a challenge record for day: 1 for the user: {did:?}");
67
67
+
return Err(AdventError::ShouldNotHappen(
68
68
+
"Could not find challenge record".to_string(),
69
69
+
));
70
70
+
};
71
71
+
72
72
+
let record_data = match safe_check_unknown_record_parse::<advent::challenge::day::RecordData>(
73
73
+
record.value.clone(),
74
74
+
) {
75
75
+
Ok(rd) => rd,
76
76
+
Err(e) => {
77
77
+
log::error!("Error parsing record: {e}");
78
78
+
return Ok(ChallengeCheckResponse::Incorrect(format!(
79
79
+
"There is a record at the correct location, but it does not seem like it is correct. Try again:\n{e}"
80
80
+
)));
81
81
+
}
82
82
+
};
83
83
+
84
84
+
let verification_code =
85
85
+
challenge
86
86
+
.verification_code_one
87
87
+
.ok_or(AdventError::ShouldNotHappen(
88
88
+
"no verification code for day 1 challenge :/".to_string(),
89
89
+
))?;
90
90
+
91
91
+
Ok(if record_data.part_one == verification_code {
92
92
+
ChallengeCheckResponse::Correct
93
93
+
} else {
94
94
+
ChallengeCheckResponse::Incorrect(format!(
95
95
+
"The code {} is incorrect",
96
96
+
record_data.part_one
97
97
+
))
98
98
+
})
110
99
}
111
100
112
101
///TODO this is just a straight copy and paste of part one since it's a proof of concept needs to share code better between the two
···
128
117
.get_record(
129
118
atrium_api::com::atproto::repo::get_record::ParametersData {
130
119
cid: None,
131
131
-
collection: crate::lexicons::codes::advent::challenge::Day::NSID
132
132
-
.parse()
133
133
-
.unwrap(),
120
120
+
collection: advent::challenge::Day::NSID.parse().unwrap(),
134
121
repo: did.parse().unwrap(),
135
122
rkey: "1".parse().unwrap(),
136
123
}
···
140
127
{
141
128
Ok(record) => {
142
129
//TODO trouble, and make it double
143
143
-
let challenge = self.get_days_challenge(did.clone()).await?;
130
130
+
let challenge = self.get_days_challenge(&did).await?;
144
131
145
132
match challenge {
146
133
None => {
···
156
143
Some(challenge) => {
157
144
let parse_record_result =
158
145
safe_check_unknown_record_parse::<
159
159
-
crate::lexicons::codes::advent::challenge::day::RecordData,
146
146
+
advent::challenge::day::RecordData,
160
147
>(record.value.clone());
161
148
162
149
match parse_record_result {
+2
-3
shared/src/advent/mod.rs
+2
-3
shared/src/advent/mod.rs
···
186
186
187
187
async fn get_days_challenge(
188
188
&self,
189
189
-
did: String,
189
189
+
did: &str,
190
190
) -> Result<Option<ChallengeProgress>, AdventError> {
191
191
-
let day = self.day();
192
191
Ok(sqlx::query_as::<_, ChallengeProgress>(
193
192
"SELECT * FROM challenges WHERE user_did = $1 AND day = $2",
194
193
)
195
194
.bind(did)
196
196
-
.bind(day as i16)
195
195
+
.bind(self.day() as i16)
197
196
.fetch_optional(self.pool())
198
197
.await?)
199
198
}
+2
-2
web/src/handlers/day.rs
+2
-2
web/src/handlers/day.rs
···
83
83
.markdown_text_part_one(None)
84
84
.map(|s| s.to_string())
85
85
.unwrap_or_else(|_| "Error loading part one".to_string()),
86
86
-
Some(ref users_did) => match challenge.get_days_challenge(users_did.clone()).await {
86
86
+
Some(ref users_did) => match challenge.get_days_challenge(&users_did).await {
87
87
Ok(current_challenge) => match current_challenge {
88
88
None => {
89
89
let new_code = challenge
···
186
186
.markdown_text_part_two(None)
187
187
.map(|opt| opt.map(|s| s.to_string()))
188
188
.unwrap_or(None),
189
189
-
Some(users_did) => match challenge.get_days_challenge(users_did.clone()).await {
189
189
+
Some(users_did) => match challenge.get_days_challenge(&users_did).await {
190
190
Ok(current_challenge) => match current_challenge {
191
191
None => {
192
192
if challenge.has_part_two() {