akinator/
enums.rs

1use pyo3::{
2    prelude::*,
3    types::PyType,
4};
5
6use crate::error::Error;
7use akinator_rs::enums::{
8    Theme as ThemeEnum,
9    Answer as AnswerEnum,
10    Language as LanguageEnum,
11};
12
13
14macro_rules! cast_enum {
15    ( $from:ty, $to:ty, $item:expr, $( $var:tt ),* $(,)* ) => {{
16        match $item {
17            $(
18                <$from>::$var => <$to>::$var,
19            )*
20        }
21    }};
22}
23
24/// An enum class representing an answer given to the akinator
25///
26/// This is meant for the user to use to pass into methods such as `Akinator.answer`
27#[pyclass]
28#[derive(Clone, Copy, Debug, PartialEq, Eq)]
29pub enum Answer {
30    Yes = 0,
31    No = 1,
32    Idk = 2,
33    Probably = 3,
34    ProbablyNot = 4,
35}
36
37/// An enum class representing the theme of an akinator game
38///
39/// This is meant for the user to use to pass into the Akinator constructor, or to set the theme property
40#[pyclass]
41#[derive(Clone, Copy, Debug, PartialEq, Eq)]
42pub enum Theme {
43    Characters = 1,
44    Animals = 14,
45    Objects = 2,
46}
47
48/// An enum class representing the language of the akinator game
49///
50/// This is meant for the user to use to pass into the Akinator constructor, or to set the language property
51#[pyclass]
52#[derive(Clone, Copy, Debug, PartialEq, Eq)]
53pub enum Language {
54    English,
55    Arabic,
56    Chinese,
57    German,
58    Spanish,
59    French,
60    Hebrew,
61    Italian,
62    Japanese,
63    Korean,
64    Dutch,
65    Polish,
66    Portugese,
67    Russian,
68    Turkish,
69    Indonesian,
70}
71
72#[pymethods]
73impl Answer {
74    /// a classmethod to return an :class:`Answer` enum variant parsing from a :class:`str`
75    /// useful when you have external user input
76    ///
77    /// aliases for answer variants are also accepted (trims ws & case-insensitive):
78    ///     - ``yes | y | 0`` -> ``Answer.Yes``
79    ///     - ``no | n | 1`` -> ``Answer.No``
80    ///     - ``i don(')?t know | idk | 2`` -> ``Answer.Idk``
81    ///     - ``probably | p | 3`` -> ``Answer.Probably``
82    ///     - ``probably not | pn | 4`` -> ``Answer.ProbablyNot``
83    ///
84    /// Raises
85    /// ------
86    /// :class:`InvalidAnswer`
87    ///     raised if the provided answer cannot match one of the above (is invalid)
88    #[classmethod]
89    #[pyo3(text_signature = "(self, answer)")]
90    fn from_str(_cls: &PyType, answer: String) -> PyResult<Self> {
91        AnswerEnum::try_from(answer)
92            .map_err(|e| Error::from(e).into())
93            .map(Self::from)
94    }
95
96    fn __repr__(&self) -> String {
97        format!("<Answer answer=\"{:?}\">", self)
98    }
99
100    fn __str__(&self) -> String {
101        format!("{:?}", self)
102    }
103}
104
105#[pymethods]
106impl Theme {
107    /// a classmethod to return a :class:`Theme` enum variant parsing from a :class:`str`
108    /// useful when you have external user input
109    ///
110    /// .. note ::
111    ///     if an invalid string for the theme is given, no error will be raised
112    ///     instead it will just fallback to ``Theme.Characters`` as the default
113    #[classmethod]
114    #[pyo3(text_signature = "(self, theme)")]
115    fn from_str(_cls: &PyType, theme: String) -> Self {
116        Self::from(ThemeEnum::from(theme))
117    }
118
119    fn __repr__(&self) -> String {
120        format!("<Theme theme=\"{:?}\">", self)
121    }
122
123    fn __str__(&self) -> String {
124        format!("{:?}", self)
125    }
126}
127
128#[pymethods]
129impl Language {
130    /// a classmethod to return a :class:`Language` enum variant parsing from a :class:`str`
131    /// useful when you have external user input
132    ///
133    /// Short forms such as ``en`` or ``fr`` are also accepted along with the full name
134    ///
135    /// Raises
136    /// ------
137    /// :class:`InvalidLanguage`
138    ///     Raised if the given string is of an invalid language
139    #[classmethod]
140    #[pyo3(text_signature = "(self, language)")]
141    fn from_str(_cls: &PyType, language: String) -> PyResult<Self> {
142        LanguageEnum::try_from(language)
143            .map_err(|e| Error::from(e).into())
144            .map(Self::from)
145    }
146
147    fn __repr__(&self) -> String {
148        format!("<Language lang=\"{:?}\">", self)
149    }
150
151    fn __str__(&self) -> String {
152        format!("{:?}", self)
153    }
154}
155
156impl From<AnswerEnum> for Answer {
157    fn from(answer: AnswerEnum) -> Self {
158        cast_enum!(
159            AnswerEnum,
160            Self,
161            answer,
162            Yes,
163            No,
164            Idk,
165            Probably,
166            ProbablyNot,
167        )
168    }
169}
170
171impl From<Answer> for AnswerEnum {
172    fn from(answer: Answer) -> Self {
173        cast_enum!(
174            Answer,
175            Self,
176            answer,
177            Yes,
178            No,
179            Idk,
180            Probably,
181            ProbablyNot,
182        )
183    }
184}
185
186impl From<ThemeEnum> for Theme {
187    fn from(theme: ThemeEnum) -> Self {
188        cast_enum!(
189            ThemeEnum,
190            Self,
191            theme,
192            Characters,
193            Animals,
194            Objects,
195        )
196    }
197}
198
199impl From<Theme> for ThemeEnum {
200    fn from(theme: Theme) -> Self {
201        cast_enum!(
202            Theme,
203            Self,
204            theme,
205            Characters,
206            Animals,
207            Objects,
208        )
209    }
210}
211
212impl From<LanguageEnum> for Language {
213    fn from(language: LanguageEnum) -> Self {
214        cast_enum!(
215            LanguageEnum,
216            Self,
217            language,
218            English,
219            Arabic,
220            Chinese,
221            German,
222            Spanish,
223            French,
224            Hebrew,
225            Italian,
226            Japanese,
227            Korean,
228            Dutch,
229            Polish,
230            Portugese,
231            Russian,
232            Turkish,
233            Indonesian,
234        )
235    }
236}
237
238impl From<Language> for LanguageEnum {
239    fn from(language: Language) -> Self {
240        cast_enum!(
241            Language,
242            Self,
243            language,
244            English,
245            Arabic,
246            Chinese,
247            German,
248            Spanish,
249            French,
250            Hebrew,
251            Italian,
252            Japanese,
253            Korean,
254            Dutch,
255            Polish,
256            Portugese,
257            Russian,
258            Turkish,
259            Indonesian,
260        )
261    }
262}