akinator_rs/
enums.rs

1use std::{
2    fmt,
3    str::FromStr,
4};
5
6use crate::error::{Result, Error};
7
8
9/// Enum representing a user's answer to the akinator's questions
10///
11/// intended to be passed into [`Akinator::answer`]
12///
13/// for parsing from a string, use the `from_str` / [`str::parse`] or `try_from` methods
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub enum Answer {
16    Yes = 0,
17    No = 1,
18    Idk = 2,
19    Probably = 3,
20    ProbablyNot = 4,
21}
22
23/// Enum representing the theme of the akinator game
24///
25/// intended to be pased into [`Akinator::with_theme`] when setting the theme of the game
26///
27/// for parsing from a string, use the `from_str` / [`str::parse`] or `from` methods
28#[derive(Clone, Copy, Debug, PartialEq, Eq)]
29pub enum Theme {
30    Characters = 1,
31    Animals = 14,
32    Objects = 2,
33}
34
35/// Enum representing the language of the akinator game
36///
37/// intended to be pased into [`Akinator::with_language`] when setting the language of the game
38///
39/// for parsing from a string, use the `from_str` / [`str::parse`] or `try_from` methods
40#[derive(Clone, Copy, Debug, PartialEq, Eq)]
41pub enum Language {
42    English,
43    Arabic,
44    Chinese,
45    German,
46    Spanish,
47    French,
48    Hebrew,
49    Italian,
50    Japanese,
51    Korean,
52    Dutch,
53    Polish,
54    Portugese,
55    Russian,
56    Turkish,
57    Indonesian,
58}
59
60/// internal method attempting to convert a string answer: (ex: "yes")
61/// to an [`Answer`] variant
62///
63/// used in [`FromStr`] and [`TryFrom`] implementations
64#[allow(clippy::needless_pass_by_value)]
65fn try_answer_from_string(ans: String) -> Result<Answer> {
66    match ans.trim().to_lowercase().as_str() {
67        "yes" | "y" | "0" => Ok(Answer::Yes),
68        "no"  | "n" | "1" => Ok(Answer::No),
69        "i dont know" | "i don't know" | "idk" | "i" | "2" => Ok(Answer::Idk),
70        "probably" | "p" | "3" => Ok(Answer::Probably),
71        "probably not" | "pn" | "4" => Ok(Answer::ProbablyNot),
72        _ => Err(Error::InvalidAnswer),
73    }
74}
75
76impl FromStr for Answer {
77    type Err = Error;
78
79    fn from_str(string: &str) -> Result<Self, Self::Err> {
80        try_answer_from_string(string.to_string())
81    }
82}
83
84impl TryFrom<&str> for Answer {
85    type Error = Error;
86
87    fn try_from(ans: &str) -> Result<Self, Self::Error> {
88        try_answer_from_string(ans.to_string())
89    }
90}
91
92impl TryFrom<String> for Answer {
93    type Error = Error;
94
95    fn try_from(ans: String) -> Result<Self, Self::Error> {
96        try_answer_from_string(ans)
97    }
98}
99
100impl TryFrom<usize> for Answer {
101    type Error = Error;
102
103    fn try_from(ans: usize) -> Result<Self, Self::Error> {
104        try_answer_from_string(ans.to_string())
105    }
106}
107
108/// internal method to convert a string representing a theme: (ex: "animals")
109/// to a [`Theme`] variant
110///
111/// used in [`FromStr`] and [`From`] implementations
112#[allow(clippy::needless_pass_by_value)]
113fn theme_from_string(theme: String) -> Theme {
114    match theme.trim().to_lowercase().as_str() {
115        "a" | "animals" => Theme::Animals,
116        "o" | "objects" => Theme::Objects,
117        _ => Theme::default(),
118    }
119}
120
121impl Default for Theme {
122    fn default() -> Self {
123        Self::Characters
124    }
125}
126
127impl FromStr for Theme {
128    type Err = Error;
129
130    fn from_str(string: &str) -> Result<Self, Self::Err> {
131        Ok(theme_from_string(string.to_string()))
132    }
133}
134
135impl From<&str> for Theme {
136    fn from(theme: &str) -> Self {
137        theme_from_string(theme.to_string())
138    }
139}
140
141impl From<String> for Theme {
142    fn from(theme: String) -> Self {
143        theme_from_string(theme)
144    }
145}
146
147impl From<usize> for Theme {
148    fn from(theme: usize) -> Self {
149        theme_from_string(theme.to_string())
150    }
151}
152
153
154impl fmt::Display for Language {
155    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156        f.write_str(match self {
157            Self::English => "en",
158            Self::Arabic => "ar",
159            Self::Chinese => "cn",
160            Self::German => "de",
161            Self::Spanish => "es",
162            Self::French => "fr",
163            Self::Hebrew => "il",
164            Self::Italian => "it",
165            Self::Japanese => "jp",
166            Self::Korean => "kr",
167            Self::Dutch => "nl",
168            Self::Polish => "pl",
169            Self::Portugese => "pt",
170            Self::Russian => "ru",
171            Self::Turkish => "tr",
172            Self::Indonesian => "id",
173        })
174    }
175}
176
177/// internal method attempting to convert a string representing a language: (ex: "english")
178/// to a [`Language`] variant
179///
180/// used in [`FromStr`] and [`TryFrom`] implementations
181#[allow(clippy::needless_pass_by_value)]
182fn try_lang_from_string(lang: String) -> Result<Language> {
183    match lang.trim().to_lowercase().as_str() {
184        "english" | "en" => Ok(Language::English),
185        "arabic"  | "ar" => Ok(Language::Arabic),
186        "chinese" | "cn" => Ok(Language::Chinese),
187        "spanish" | "es" => Ok(Language::Spanish),
188        "french"  | "fr" => Ok(Language::French),
189        "hebrew"  | "il" => Ok(Language::Hebrew),
190        "italian" | "it" => Ok(Language::Italian),
191        "japanese" | "jp" => Ok(Language::Japanese),
192        "korean"  | "kr" => Ok(Language::Korean),
193        "dutch"  | "nl" => Ok(Language::Dutch),
194        "polish" | "pl" => Ok(Language::Polish),
195        "portugese" | "pt" => Ok(Language:: Portugese),
196        "russian" | "ru" => Ok(Language::Russian),
197        "turkish" | "tr" => Ok(Language::Turkish),
198        "indonesian" | "id" => Ok(Language::Indonesian),
199        "german" | "de" => Ok(Language::German),
200        _ => Err(Error::InvalidLanguage)
201    }
202}
203
204impl Default for Language {
205    fn default() -> Self {
206        Self::English
207    }
208}
209
210impl FromStr for Language {
211    type Err = Error;
212
213    fn from_str(string: &str) -> Result<Self, Self::Err> {
214        try_lang_from_string(string.to_string())
215    }
216}
217
218impl TryFrom<&str> for Language {
219    type Error = Error;
220
221    fn try_from(ans: &str) -> Result<Self, Self::Error> {
222        try_lang_from_string(ans.to_string())
223    }
224}
225
226
227impl TryFrom<String> for Language {
228    type Error = Error;
229
230    fn try_from(ans: String) -> Result<Self, Self::Error> {
231        try_lang_from_string(ans)
232    }
233}