Style: flatten code for day1 part1 challenge #4

merged
opened by bad-example.com targeting main from bad-example.com/at-advent: flatten-challenge-check

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!

Changed files
+69 -83
shared
src
advent
challenges
web
src
handlers
+65 -78
shared/src/advent/challenges/day_one.rs
···
use crate::advent::day::Day;
use crate::advent::{AdventChallenge, AdventError, ChallengeCheckResponse};
use crate::atrium::safe_check_unknown_record_parse;
use async_trait::async_trait;
use atrium_api::types::Collection;
use sqlx::PgPool;
···
did: String,
_verification_code: Option<String>,
) -> Result<ChallengeCheckResponse, AdventError> {
-
match &self.oauth_client {
-
None => Err(AdventError::ShouldNotHappen(
"No oauth client. This should not happen".to_string(),
-
)),
-
Some(client) => {
-
match client
-
.api
-
.com
-
.atproto
-
.repo
-
.get_record(
-
atrium_api::com::atproto::repo::get_record::ParametersData {
-
cid: None,
-
collection: crate::lexicons::codes::advent::challenge::Day::NSID
-
.parse()
-
.unwrap(),
-
repo: did.parse().unwrap(),
-
rkey: "1".parse().unwrap(),
-
}
-
.into(),
-
)
-
.await
-
{
-
Ok(record) => {
-
//TODO trouble, and make it double
-
let challenge = self.get_days_challenge(did.clone()).await?;
-
-
match challenge {
-
None => {
-
log::error!(
-
"Could not find a challenge record for day: {} for the user: {}",
-
self.day(),
-
did.clone()
-
);
-
Err(AdventError::ShouldNotHappen(
-
"Could not find a challenge record".to_string(),
-
))
-
}
-
Some(challenge) => {
-
let parse_record_result =
-
safe_check_unknown_record_parse::<
-
crate::lexicons::codes::advent::challenge::day::RecordData,
-
>(record.value.clone());
-
match parse_record_result {
-
Ok(record_data) => {
-
match record_data.part_one
-
== challenge
-
.verification_code_one
-
.unwrap_or("".to_string())
-
{
-
true => Ok(ChallengeCheckResponse::Correct),
-
false => {
-
Ok(ChallengeCheckResponse::Incorrect(format!(
-
"The code {} is incorrect",
-
record_data.part_one
-
)))
-
}
-
}
-
}
-
Err(err) => {
-
log::error!("Error parsing record: {}", err);
-
Ok(ChallengeCheckResponse::Incorrect(format!(
-
"There is a record at the correct location, but it does not seem like it is correct. Try again:\n{err}"
-
)))
-
}
-
}
-
}
-
}
-
}
-
Err(err) => {
-
log::error!("Error getting record: {}", err);
-
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()))
-
}
}
}
-
}
}
///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
···
.get_record(
atrium_api::com::atproto::repo::get_record::ParametersData {
cid: None,
-
collection: crate::lexicons::codes::advent::challenge::Day::NSID
-
.parse()
-
.unwrap(),
repo: did.parse().unwrap(),
rkey: "1".parse().unwrap(),
}
···
{
Ok(record) => {
//TODO trouble, and make it double
-
let challenge = self.get_days_challenge(did.clone()).await?;
match challenge {
None => {
···
Some(challenge) => {
let parse_record_result =
safe_check_unknown_record_parse::<
-
crate::lexicons::codes::advent::challenge::day::RecordData,
>(record.value.clone());
match parse_record_result {
···
use crate::advent::day::Day;
use crate::advent::{AdventChallenge, AdventError, ChallengeCheckResponse};
use crate::atrium::safe_check_unknown_record_parse;
+
use crate::lexicons::codes::advent;
use async_trait::async_trait;
use atrium_api::types::Collection;
use sqlx::PgPool;
···
did: String,
_verification_code: Option<String>,
) -> Result<ChallengeCheckResponse, AdventError> {
+
let client = self
+
.oauth_client
+
.as_ref()
+
.ok_or(AdventError::ShouldNotHappen(
"No oauth client. This should not happen".to_string(),
+
))?;
+
let record_res = client
+
.api
+
.com
+
.atproto
+
.repo
+
.get_record(
+
atrium_api::com::atproto::repo::get_record::ParametersData {
+
cid: None,
+
collection: advent::challenge::Day::NSID.parse().unwrap(),
+
repo: did.parse().unwrap(),
+
rkey: "1".parse().unwrap(),
}
+
.into(),
+
)
+
.await;
+
+
let record = match record_res {
+
Ok(r) => r,
+
Err(e) => {
+
log::error!("Error getting record: {}", e);
+
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()));
}
+
};
+
+
let Some(challenge) = self.get_days_challenge(&did).await? else {
+
log::error!("Could not find a challenge record for day: 1 for the user: {did:?}");
+
return Err(AdventError::ShouldNotHappen(
+
"Could not find challenge record".to_string(),
+
));
+
};
+
+
let record_data = match safe_check_unknown_record_parse::<advent::challenge::day::RecordData>(
+
record.value.clone(),
+
) {
+
Ok(rd) => rd,
+
Err(e) => {
+
log::error!("Error parsing record: {e}");
+
return Ok(ChallengeCheckResponse::Incorrect(format!(
+
"There is a record at the correct location, but it does not seem like it is correct. Try again:\n{e}"
+
)));
+
}
+
};
+
+
let verification_code =
+
challenge
+
.verification_code_one
+
.ok_or(AdventError::ShouldNotHappen(
+
"no verification code for day 1 challenge :/".to_string(),
+
))?;
+
+
Ok(if record_data.part_one == verification_code {
+
ChallengeCheckResponse::Correct
+
} else {
+
ChallengeCheckResponse::Incorrect(format!(
+
"The code {} is incorrect",
+
record_data.part_one
+
))
+
})
}
///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
···
.get_record(
atrium_api::com::atproto::repo::get_record::ParametersData {
cid: None,
+
collection: advent::challenge::Day::NSID.parse().unwrap(),
repo: did.parse().unwrap(),
rkey: "1".parse().unwrap(),
}
···
{
Ok(record) => {
//TODO trouble, and make it double
+
let challenge = self.get_days_challenge(&did).await?;
match challenge {
None => {
···
Some(challenge) => {
let parse_record_result =
safe_check_unknown_record_parse::<
+
advent::challenge::day::RecordData,
>(record.value.clone());
match parse_record_result {
+2 -3
shared/src/advent/mod.rs
···
async fn get_days_challenge(
&self,
-
did: String,
) -> Result<Option<ChallengeProgress>, AdventError> {
-
let day = self.day();
Ok(sqlx::query_as::<_, ChallengeProgress>(
"SELECT * FROM challenges WHERE user_did = $1 AND day = $2",
)
.bind(did)
-
.bind(day as i16)
.fetch_optional(self.pool())
.await?)
}
···
async fn get_days_challenge(
&self,
+
did: &str,
) -> Result<Option<ChallengeProgress>, AdventError> {
Ok(sqlx::query_as::<_, ChallengeProgress>(
"SELECT * FROM challenges WHERE user_did = $1 AND day = $2",
)
.bind(did)
+
.bind(self.day() as i16)
.fetch_optional(self.pool())
.await?)
}
+2 -2
web/src/handlers/day.rs
···
.markdown_text_part_one(None)
.map(|s| s.to_string())
.unwrap_or_else(|_| "Error loading part one".to_string()),
-
Some(ref users_did) => match challenge.get_days_challenge(users_did.clone()).await {
Ok(current_challenge) => match current_challenge {
None => {
let new_code = challenge
···
.markdown_text_part_two(None)
.map(|opt| opt.map(|s| s.to_string()))
.unwrap_or(None),
-
Some(users_did) => match challenge.get_days_challenge(users_did.clone()).await {
Ok(current_challenge) => match current_challenge {
None => {
if challenge.has_part_two() {
···
.markdown_text_part_one(None)
.map(|s| s.to_string())
.unwrap_or_else(|_| "Error loading part one".to_string()),
+
Some(ref users_did) => match challenge.get_days_challenge(&users_did).await {
Ok(current_challenge) => match current_challenge {
None => {
let new_code = challenge
···
.markdown_text_part_two(None)
.map(|opt| opt.map(|s| s.to_string()))
.unwrap_or(None),
+
Some(users_did) => match challenge.get_days_challenge(&users_did).await {
Ok(current_challenge) => match current_challenge {
None => {
if challenge.has_part_two() {