Skip to content

Commit d7dd8f2

Browse files
committed
refactor(playmatch): extract shared api-error helper and manual_match_mode method
1 parent 5cf83a4 commit d7dd8f2

2 files changed

Lines changed: 74 additions & 150 deletions

File tree

src/abstraction/playmatch.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,60 @@
11
use crate::abstraction::command::{CommandContext, paginate};
2+
use crate::abstraction::components_v2::{self, Status};
23
use crate::util::create_discord_markdown_table;
4+
use log::warn;
5+
use playmatch_client::Error;
36
use playmatch_client::types::{
47
CompanyMetadataResponse, ExternalMetadata, MetadataMatchType, MetadataProvider,
58
PlatformMetadataResponse,
69
};
10+
use reqwest::StatusCode;
711
use uuid::Uuid;
812

13+
pub enum ApiErrorAction {
14+
Suggest,
15+
Match,
16+
}
17+
18+
pub async fn send_playmatch_api_error<E: std::fmt::Debug>(
19+
ctx: CommandContext<'_>,
20+
e: &Error<E>,
21+
entity: &str,
22+
identifier: &str,
23+
action: ApiErrorAction,
24+
) -> Result<(), serenity::Error> {
25+
let action_verb = match action {
26+
ApiErrorAction::Suggest => "submit suggestion for",
27+
ApiErrorAction::Match => "match",
28+
};
29+
30+
if let Error::ErrorResponse(e_res) = e {
31+
if e_res.status() == StatusCode::NOT_FOUND {
32+
ctx.send(components_v2::status_reply(
33+
Status::Error,
34+
format!("No {entity} found for the provided {identifier}."),
35+
))
36+
.await?;
37+
return Ok(());
38+
}
39+
if e_res.status() == StatusCode::CONFLICT && matches!(action, ApiErrorAction::Suggest) {
40+
ctx.send(components_v2::status_reply(
41+
Status::Error,
42+
format!("A suggestion for this {entity} already exists from the same provider."),
43+
))
44+
.await?;
45+
return Ok(());
46+
}
47+
}
48+
49+
ctx.send(components_v2::status_reply(
50+
Status::Error,
51+
format!("Failed to {action_verb} {entity}: {e}"),
52+
))
53+
.await?;
54+
warn!("Failed to {action_verb} {entity}: {e}");
55+
Ok(())
56+
}
57+
958
pub trait PlaymatchResponse {
1059
fn get_id(&self) -> Uuid;
1160
fn get_name(&self) -> String;

src/command/playmatch.rs

Lines changed: 25 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ use crate::abstraction::command::{
33
};
44
use crate::abstraction::components_v2::{self, Card, Status};
55
use crate::abstraction::igdb;
6-
use crate::abstraction::playmatch::paginate_playmatch_response;
6+
use crate::abstraction::playmatch::{
7+
ApiErrorAction, paginate_playmatch_response, send_playmatch_api_error,
8+
};
79
use crate::command::SUGGESTION_CHANNEL_ID;
810
use anyhow::anyhow;
911
use log::{debug, error, warn};
10-
use playmatch_client::Error;
1112
use playmatch_client::types::ManualMatchMode::{Admin, Trusted};
1213
use playmatch_client::types::MetadataProvider::Igdb;
1314
use playmatch_client::types::{
1415
CompanyOrPlatformMatchRequest, CompanyOrPlatformSuggestionRequest, CreateOrGetUserRequest,
15-
GameMatchRequest, GameMatchType, GameSuggestionRequest, MetadataMatchType,
16+
GameMatchRequest, GameMatchType, GameSuggestionRequest, ManualMatchMode, MetadataMatchType,
1617
UpdateUserPermissionsRequest, UserPermissions,
1718
};
18-
use reqwest::StatusCode;
1919
use serenity::all::{
2020
ButtonStyle, Cache, ChannelId, ComponentInteractionCollector, Context, CreateButton,
2121
CreateComponent, CreateInteractionResponse, CreateInteractionResponseMessage, EditMessage,
@@ -337,31 +337,8 @@ pub async fn create_game_suggestion(
337337
let suggestion = match result {
338338
Ok(suggestion_value) => suggestion_value.into_inner(),
339339
Err(e) => {
340-
match &e {
341-
Error::ErrorResponse(e_res) => {
342-
if e_res.status() == StatusCode::NOT_FOUND {
343-
ctx.send(components_v2::status_reply(
344-
Status::Error,
345-
"No Game found for the provided hashes or name.",
346-
))
347-
.await?;
348-
} else if e_res.status() == StatusCode::CONFLICT {
349-
ctx.send(components_v2::status_reply(
350-
Status::Error,
351-
"A suggestion for this Game already exists from the same provider.",
352-
))
353-
.await?;
354-
}
355-
}
356-
_ => {
357-
ctx.send(components_v2::status_reply(
358-
Status::Error,
359-
format!("Failed to submit suggestion for Game: {e}"),
360-
))
361-
.await?;
362-
warn!("Failed to submit suggestion for Game: {e}");
363-
}
364-
}
340+
send_playmatch_api_error(ctx, &e, "Game", "hashes or name", ApiErrorAction::Suggest)
341+
.await?;
365342
return Ok(());
366343
}
367344
};
@@ -461,31 +438,7 @@ pub async fn create_company_suggestion(
461438
let suggestion = match result {
462439
Ok(suggestion_value) => suggestion_value.into_inner(),
463440
Err(e) => {
464-
match &e {
465-
Error::ErrorResponse(e_res) => {
466-
if e_res.status() == StatusCode::NOT_FOUND {
467-
ctx.send(components_v2::status_reply(
468-
Status::Error,
469-
"No Company found for the provided name.",
470-
))
471-
.await?;
472-
} else if e_res.status() == StatusCode::CONFLICT {
473-
ctx.send(components_v2::status_reply(
474-
Status::Error,
475-
"A suggestion for this Company already exists from the same provider.",
476-
))
477-
.await?;
478-
}
479-
}
480-
_ => {
481-
ctx.send(components_v2::status_reply(
482-
Status::Error,
483-
format!("Failed to submit suggestion for Company: {e}"),
484-
))
485-
.await?;
486-
warn!("Failed to submit suggestion for Company: {e}");
487-
}
488-
}
441+
send_playmatch_api_error(ctx, &e, "Company", "name", ApiErrorAction::Suggest).await?;
489442
return Ok(());
490443
}
491444
};
@@ -564,31 +517,7 @@ pub async fn create_platform_suggestion(
564517
let suggestion = match result {
565518
Ok(suggestion_value) => suggestion_value.into_inner(),
566519
Err(e) => {
567-
match &e {
568-
Error::ErrorResponse(e_res) => {
569-
if e_res.status() == StatusCode::NOT_FOUND {
570-
ctx.send(components_v2::status_reply(
571-
Status::Error,
572-
"No Platform found for the provided name.",
573-
))
574-
.await?;
575-
} else if e_res.status() == StatusCode::CONFLICT {
576-
ctx.send(components_v2::status_reply(
577-
Status::Error,
578-
"A suggestion for this Platform already exists from the same provider.",
579-
))
580-
.await?;
581-
}
582-
}
583-
_ => {
584-
ctx.send(components_v2::status_reply(
585-
Status::Error,
586-
format!("Failed to submit suggestion for Platform: {e}"),
587-
))
588-
.await?;
589-
warn!("Failed to submit suggestion for Platform: {e}");
590-
}
591-
}
520+
send_playmatch_api_error(ctx, &e, "Platform", "name", ApiErrorAction::Suggest).await?;
592521
return Ok(());
593522
}
594523
};
@@ -675,11 +604,7 @@ pub async fn manual_match_platform(
675604
.playmatch_client
676605
.manually_match_platform()
677606
.body(CompanyOrPlatformMatchRequest {
678-
manual_match_type: if playmatch_user_ctx.is_admin {
679-
Admin
680-
} else {
681-
Trusted
682-
},
607+
manual_match_type: playmatch_user_ctx.manual_match_mode(),
683608
provider_id: igdb_id.to_string(),
684609
provider: Igdb,
685610
name,
@@ -690,25 +615,8 @@ pub async fn manual_match_platform(
690615
.await;
691616

692617
if let Err(e) = &result {
693-
match e {
694-
Error::ErrorResponse(e_res) if e_res.status() == StatusCode::NOT_FOUND => {
695-
ctx.send(components_v2::status_reply(
696-
Status::Error,
697-
"No Platform found for the provided name.",
698-
))
699-
.await?;
700-
return Ok(());
701-
}
702-
_ => {
703-
ctx.send(components_v2::status_reply(
704-
Status::Error,
705-
format!("Failed to match Platform: {e}"),
706-
))
707-
.await?;
708-
warn!("Failed to match Platform: {e}");
709-
return Ok(());
710-
}
711-
}
618+
send_playmatch_api_error(ctx, e, "Platform", "name", ApiErrorAction::Match).await?;
619+
return Ok(());
712620
}
713621

714622
let igdb_id_str = igdb_id.to_string();
@@ -746,11 +654,7 @@ pub async fn manual_match_company(
746654
.playmatch_client
747655
.manually_match_company()
748656
.body(CompanyOrPlatformMatchRequest {
749-
manual_match_type: if playmatch_user_ctx.is_admin {
750-
Admin
751-
} else {
752-
Trusted
753-
},
657+
manual_match_type: playmatch_user_ctx.manual_match_mode(),
754658
provider_id: igdb_id.to_string(),
755659
provider: Igdb,
756660
name,
@@ -761,25 +665,8 @@ pub async fn manual_match_company(
761665
.await;
762666

763667
if let Err(e) = &result {
764-
match e {
765-
Error::ErrorResponse(e_res) if e_res.status() == StatusCode::NOT_FOUND => {
766-
ctx.send(components_v2::status_reply(
767-
Status::Error,
768-
"No Company found for the provided name.",
769-
))
770-
.await?;
771-
return Ok(());
772-
}
773-
_ => {
774-
ctx.send(components_v2::status_reply(
775-
Status::Error,
776-
format!("Failed to match Company: {e}"),
777-
))
778-
.await?;
779-
warn!("Failed to match Company: {e}");
780-
return Ok(());
781-
}
782-
}
668+
send_playmatch_api_error(ctx, e, "Company", "name", ApiErrorAction::Match).await?;
669+
return Ok(());
783670
}
784671

785672
let igdb_id_str = igdb_id.to_string();
@@ -831,11 +718,7 @@ pub async fn manual_match_game(
831718
.playmatch_client
832719
.manually_match_game()
833720
.body(GameMatchRequest {
834-
manual_match_type: if playmatch_user_ctx.is_admin {
835-
Admin
836-
} else {
837-
Trusted
838-
},
721+
manual_match_type: playmatch_user_ctx.manual_match_mode(),
839722
provider_id: igdb_id.to_string(),
840723
provider: Igdb,
841724
md5: md5_hash,
@@ -849,25 +732,11 @@ pub async fn manual_match_game(
849732
.await;
850733

851734
let matched = match result {
852-
Err(e) => match &e {
853-
Error::ErrorResponse(e_res) if e_res.status() == StatusCode::NOT_FOUND => {
854-
ctx.send(components_v2::status_reply(
855-
Status::Error,
856-
"No Game found for the provided hashes or name.",
857-
))
858-
.await?;
859-
return Ok(());
860-
}
861-
_ => {
862-
ctx.send(components_v2::status_reply(
863-
Status::Error,
864-
format!("Failed to match Game: {e}"),
865-
))
735+
Err(e) => {
736+
send_playmatch_api_error(ctx, &e, "Game", "hashes or name", ApiErrorAction::Match)
866737
.await?;
867-
warn!("Failed to match Game: {e}");
868-
return Ok(());
869-
}
870-
},
738+
return Ok(());
739+
}
871740
Ok(value) => value.into_inner().len(),
872741
};
873742

@@ -898,6 +767,12 @@ struct PlaymatchUserCtx {
898767
playmatch_user: playmatch_client::types::User,
899768
}
900769

770+
impl PlaymatchUserCtx {
771+
fn manual_match_mode(&self) -> ManualMatchMode {
772+
if self.is_admin { Admin } else { Trusted }
773+
}
774+
}
775+
901776
enum SuggestionType {
902777
Platform,
903778
Company,

0 commit comments

Comments
 (0)