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
··· 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 + 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 - match &self.oauth_client { 34 - None => Err(AdventError::ShouldNotHappen( 34 + let client = self 35 + .oauth_client 36 + .as_ref() 37 + .ok_or(AdventError::ShouldNotHappen( 35 38 "No oauth client. This should not happen".to_string(), 36 - )), 37 - Some(client) => { 38 - match client 39 - .api 40 - .com 41 - .atproto 42 - .repo 43 - .get_record( 44 - atrium_api::com::atproto::repo::get_record::ParametersData { 45 - cid: None, 46 - collection: crate::lexicons::codes::advent::challenge::Day::NSID 47 - .parse() 48 - .unwrap(), 49 - repo: did.parse().unwrap(), 50 - rkey: "1".parse().unwrap(), 51 - } 52 - .into(), 53 - ) 54 - .await 55 - { 56 - Ok(record) => { 57 - //TODO trouble, and make it double 58 - let challenge = self.get_days_challenge(did.clone()).await?; 59 - 60 - match challenge { 61 - None => { 62 - log::error!( 63 - "Could not find a challenge record for day: {} for the user: {}", 64 - self.day(), 65 - did.clone() 66 - ); 67 - Err(AdventError::ShouldNotHappen( 68 - "Could not find a challenge record".to_string(), 69 - )) 70 - } 71 - Some(challenge) => { 72 - let parse_record_result = 73 - safe_check_unknown_record_parse::< 74 - crate::lexicons::codes::advent::challenge::day::RecordData, 75 - >(record.value.clone()); 39 + ))?; 76 40 77 - match parse_record_result { 78 - Ok(record_data) => { 79 - match record_data.part_one 80 - == challenge 81 - .verification_code_one 82 - .unwrap_or("".to_string()) 83 - { 84 - true => Ok(ChallengeCheckResponse::Correct), 85 - false => { 86 - Ok(ChallengeCheckResponse::Incorrect(format!( 87 - "The code {} is incorrect", 88 - record_data.part_one 89 - ))) 90 - } 91 - } 92 - } 93 - Err(err) => { 94 - log::error!("Error parsing record: {}", err); 95 - Ok(ChallengeCheckResponse::Incorrect(format!( 96 - "There is a record at the correct location, but it does not seem like it is correct. Try again:\n{err}" 97 - ))) 98 - } 99 - } 100 - } 101 - } 102 - } 103 - Err(err) => { 104 - log::error!("Error getting record: {}", err); 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 - } 41 + let record_res = client 42 + .api 43 + .com 44 + .atproto 45 + .repo 46 + .get_record( 47 + atrium_api::com::atproto::repo::get_record::ParametersData { 48 + cid: None, 49 + collection: advent::challenge::Day::NSID.parse().unwrap(), 50 + repo: did.parse().unwrap(), 51 + rkey: "1".parse().unwrap(), 107 52 } 53 + .into(), 54 + ) 55 + .await; 56 + 57 + let record = match record_res { 58 + Ok(r) => r, 59 + Err(e) => { 60 + log::error!("Error getting record: {}", e); 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 - } 63 + }; 64 + 65 + let Some(challenge) = self.get_days_challenge(&did).await? else { 66 + log::error!("Could not find a challenge record for day: 1 for the user: {did:?}"); 67 + return Err(AdventError::ShouldNotHappen( 68 + "Could not find challenge record".to_string(), 69 + )); 70 + }; 71 + 72 + let record_data = match safe_check_unknown_record_parse::<advent::challenge::day::RecordData>( 73 + record.value.clone(), 74 + ) { 75 + Ok(rd) => rd, 76 + Err(e) => { 77 + log::error!("Error parsing record: {e}"); 78 + return Ok(ChallengeCheckResponse::Incorrect(format!( 79 + "There is a record at the correct location, but it does not seem like it is correct. Try again:\n{e}" 80 + ))); 81 + } 82 + }; 83 + 84 + let verification_code = 85 + challenge 86 + .verification_code_one 87 + .ok_or(AdventError::ShouldNotHappen( 88 + "no verification code for day 1 challenge :/".to_string(), 89 + ))?; 90 + 91 + Ok(if record_data.part_one == verification_code { 92 + ChallengeCheckResponse::Correct 93 + } else { 94 + ChallengeCheckResponse::Incorrect(format!( 95 + "The code {} is incorrect", 96 + record_data.part_one 97 + )) 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 - collection: crate::lexicons::codes::advent::challenge::Day::NSID 132 - .parse() 133 - .unwrap(), 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 - let challenge = self.get_days_challenge(did.clone()).await?; 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 - crate::lexicons::codes::advent::challenge::day::RecordData, 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
··· 186 186 187 187 async fn get_days_challenge( 188 188 &self, 189 - did: String, 189 + did: &str, 190 190 ) -> Result<Option<ChallengeProgress>, AdventError> { 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 - .bind(day as i16) 195 + .bind(self.day() as i16) 197 196 .fetch_optional(self.pool()) 198 197 .await?) 199 198 }
+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 - Some(ref users_did) => match challenge.get_days_challenge(users_did.clone()).await { 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 - Some(users_did) => match challenge.get_days_challenge(users_did.clone()).await { 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() {