1#![warn(clippy::pedantic)]
2#![warn(clippy::nursery)]
3pub mod parser;
5#[cfg(feature = "tts")]
6pub mod tts;
7
8use serde::{Deserialize, Serialize};
9use std::fmt::Display;
10#[cfg(feature = "tts")]
11use tts::{CardShape, CustomDeckState};
12use uuid::Uuid;
13
14#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
15pub enum CardError {
16 CardDoesntExist {
17 card_name: String,
18 },
19 BackImageFileError {
20 card_name: String,
21 image_url: String,
22 },
23 FrontImageNotFound {
24 card_name: String,
25 image_url: String,
26 },
27 Custom {
28 message: String,
29 },
30}
31
32impl Display for CardError {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 match self {
35 Self::CardDoesntExist { card_name } => write!(f, "Card doesn't exist: {card_name}"),
36 Self::BackImageFileError {
37 card_name,
38 image_url,
39 } => write!(
40 f,
41 "Couldn't find the file for {card_name}'s back: {image_url}"
42 ),
43 Self::FrontImageNotFound {
44 card_name,
45 image_url,
46 } => write!(
47 f,
48 "Couldn't find the file for {card_name}'s front: {image_url}"
49 ),
50 Self::Custom { message } => write!(f, "{message}"),
51 }
52 }
53}
54
55impl CardError {
56 #[must_use]
57 pub const fn custom(message: String) -> Self {
58 Self::Custom { message }
59 }
60}
61
62pub trait GetCardInfo: Sized {
64 fn get_name(&self) -> &str;
66 fn get_front_image(&self) -> Result<String, CardError>;
70 fn get_back_image(&self) -> Result<String, CardError>;
74 #[cfg(feature = "tts")]
78 fn get_card_shape(&self) -> Result<CardShape, CardError>;
79 fn parse(string: &str) -> Result<Self, parser::ParseError>;
84}
85
86#[derive(Clone)]
87pub struct CardEntry<T: GetCardInfo + Clone> {
88 pub card: T,
89 pub amount: i64,
90}
91
92#[cfg(feature = "tts")]
93impl<T: GetCardInfo + Clone> CardEntry<T> {
94 pub fn get_custom_deck_state(&self) -> Result<CustomDeckState, CardError> {
97 Ok(CustomDeckState {
98 name: self.card.get_name().to_owned(),
99 face_url: self.card.get_front_image()?,
100 back_url: self.card.get_back_image()?,
101 num_width: Some(1),
102 num_height: Some(1),
103 back_is_hidden: true,
104 unique_back: false,
105 r#type: self.card.get_card_shape()?.into(),
106 })
107 }
108}
109
110#[cfg(feature = "tts")]
111fn generate_guid() -> String {
112 Uuid::new_v4().to_string()
113}