1mod action;
2mod card;
3mod player;
4
5pub use action::*;
6pub use card::*;
7pub use player::*;
8use state_validation::{StateFilterInputCombination, StateFilterInputConversion};
9
10pub trait CastTo<T> {
11 fn cast_ref(&self) -> &T;
12}
13
14#[derive(Debug)]
19pub struct MutID<ID>(ID);
20impl<ID> MutID<ID> {
21 pub(crate) fn new(id: ID) -> Self {
22 MutID(id)
23 }
24 pub fn id(&self) -> &ID {
25 &self.0
26 }
27 pub fn take_id(self) -> ID {
28 self.0
29 }
30 pub fn into_id<NewID>(self) -> MutID<NewID>
31 where
32 ID: Into<NewID>,
33 {
34 MutID(self.0.into())
35 }
36}
37pub trait IterMutID<ID> {
38 fn iter_mut_id(self) -> impl Iterator<Item = MutID<ID>>;
39}
40impl<ID> IterMutID<ID> for MutID<Vec<ID>> {
41 fn iter_mut_id(self) -> impl Iterator<Item = MutID<ID>> {
42 self.0.into_iter().map(|id| MutID::new(id))
43 }
44}
45macro_rules! mut_id_for_tuple {
46 ($($index_name: tt => $id: ident),*) => {
47 impl<$($id),*> MutID<($($id),*)> {
48 pub fn split_take(self) -> ($(MutID<$id>),*) {
49 ($(
50 MutID::new(self.0.$index_name)
51 ),*)
52 }
53 }
54 };
55}
56mut_id_for_tuple!(0 => T0, 1 => T1);
57mut_id_for_tuple!(0 => T0, 1 => T1, 2 => T2);
58mut_id_for_tuple!(0 => T0, 1 => T1, 2 => T2, 3 => T3);
59impl<T: CastTo<CastedT>, CastedT> CastTo<CastedT> for MutID<T> {
60 fn cast_ref(&self) -> &CastedT {
61 self.0.cast_ref()
62 }
63}
64impl<T: UncheckedReplaceFilter> UncheckedReplaceFilter for MutID<T> {
65 type Output<F> = MutID<T::Output<F>>;
66 fn unchecked_replace_filter<F>(self) -> Self::Output<F> {
67 MutID::new(self.0.unchecked_replace_filter())
68 }
69}
70impl<T: UncheckedClone> UncheckedClone for MutID<T> {
71 fn unchecked_clone(&self) -> Self {
72 MutID::new(self.0.unchecked_clone())
73 }
74}
75#[derive(Debug)]
76pub struct MutIDRemainder<ID>(std::marker::PhantomData<ID>);
77impl<ID> StateFilterInputConversion<ID> for MutID<ID> {
78 type Remainder = MutIDRemainder<ID>;
79 fn split_take(self) -> (ID, Self::Remainder) {
80 (self.0, MutIDRemainder(std::marker::PhantomData::default()))
81 }
82}
83impl<NewID, OldID> StateFilterInputCombination<NewID> for MutIDRemainder<OldID> {
92 type Combined = MutID<NewID>;
93 fn combine(self, new_id: NewID) -> Self::Combined {
94 MutID::new(new_id)
95 }
96}
97pub trait UncheckedReplaceFilter {
109 type Output<F>;
110 fn unchecked_replace_filter<F>(self) -> Self::Output<F>;
111}
112
113pub trait UncheckedClone {
114 fn unchecked_clone(&self) -> Self;
115}
116
117pub trait FilterSupertype<T> {}
118macro_rules! impl_filter_supertype_for_tuple {
121 ($($list_ty: ident),* | |) => {};
122 ($($list_ty: ident),* | $first_into_ty: ident $(,)? | $($lost_ty: ident),*) => {};
123 ($($list_ty: ident),* | $first_into_ty: ident, $second_into_ty: ident $(,)? | $($lost_ty: ident),*) => {};
124 ($first_ty: ident $(, $list_ty: ident)+ $(,)? | $first_into_ty: ident $(, $list_into_ty: ident)+ | $($lost_ty: ident),*) => {
125 impl<$($list_ty: FilterSupertype<$list_into_ty>,)* $($lost_ty,)* $($list_into_ty,)* $first_ty> FilterSupertype<($($list_into_ty),*)> for ($($list_ty,)* $($lost_ty,)* $first_ty) {}
126 impl_filter_supertype_for_tuple!($($list_ty),* | $($list_into_ty),* | $($lost_ty,)* $first_ty);
127 };
128 ($($list_ty: ident),+ | $($list_into_ty: ident),+ $(,)?) => {
129 impl<$($list_ty: FilterSupertype<$list_into_ty>,)* $($list_into_ty),*> FilterSupertype<($($list_into_ty),*)> for ($($list_ty),*) {}
130 impl_filter_supertype_for_tuple!($($list_ty),* | $($list_into_ty),* |);
131 };
132}
133impl_filter_supertype_for_tuple!(T0, T1 | IntoT0, IntoT1);
134impl_filter_supertype_for_tuple!(T0, T1, T2 | IntoT0, IntoT1, IntoT2);
135impl_filter_supertype_for_tuple!(T0, T1, T2, T3 | IntoT0, IntoT1, IntoT2, IntoT3);
136impl_filter_supertype_for_tuple!(T0, T1, T2, T3, T4 | IntoT0, IntoT1, IntoT2, IntoT3, IntoT4);
137impl_filter_supertype_for_tuple!(
138 T0,
139 T1,
140 T2,
141 T3,
142 T4,
143 T5 | IntoT0,
144 IntoT1,
145 IntoT2,
146 IntoT3,
147 IntoT4,
148 IntoT5,
149);
150impl_filter_supertype_for_tuple!(
151 T0,
152 T1,
153 T2,
154 T3,
155 T4,
156 T5,
157 T6 | IntoT0,
158 IntoT1,
159 IntoT2,
160 IntoT3,
161 IntoT4,
162 IntoT5,
163 IntoT6,
164);
165impl_filter_supertype_for_tuple!(
166 T0,
167 T1,
168 T2,
169 T3,
170 T4,
171 T5,
172 T6,
173 T7 | IntoT0,
174 IntoT1,
175 IntoT2,
176 IntoT3,
177 IntoT4,
178 IntoT5,
179 IntoT6,
180 IntoT7,
181);
182
183#[macro_export]
208macro_rules! create_valid_identification {
209 ($name: ident, $internal_id: ty, with_copy) => {
210 create_valid_identification!($name, $internal_id, core);
211 impl<F> $name<F> {
212 pub fn id(&self) -> $internal_id {
213 self.0
214 }
215 }
216 };
217 ($name: ident, $internal_id: ty, with_clone) => {
218 create_valid_identification!($name, $internal_id, core);
219 impl<F> $name<F> {
220 pub fn id(&self) -> $internal_id {
221 self.0.clone()
222 }
223 }
224 };
225 ($name: ident, $internal_id: ty) => {
226 create_valid_identification!($name, $internal_id, core);
227 impl<F> $name<F> {
228 pub fn id(&self) -> &$internal_id {
229 &self.0
230 }
231 }
232 };
233 ($name: ident, $internal_id: ty, core) => {
234 pub struct $name<F>($internal_id, ::std::marker::PhantomData<(F, *const ())>);
235 impl<F> std::fmt::Debug for $name<F>
236 where
237 $internal_id: std::fmt::Debug,
238 {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 write!(f, "Valid({:?})", &self.0)
241 }
242 }
243 impl<F> card_game::stack::NonEmptyInput for $name<F> {}
244 impl<F> card_game::identifications::UncheckedReplaceFilter for $name<F> {
245 type Output<NewF> = $name<NewF>;
246 fn unchecked_replace_filter<NewF>(self) -> Self::Output<NewF> {
247 $name(self.0, ::std::marker::PhantomData::default())
248 }
249 }
250 impl<F> card_game::identifications::UncheckedClone for $name<F> {
251 fn unchecked_clone(&self) -> Self {
252 Self(self.0.clone(), ::std::marker::PhantomData::default())
253 }
254 }
255 impl<F> $name<F> {
256 pub fn get<T>(
257 &self,
258 f: impl ::std::ops::FnOnce(&Self) -> ::std::option::Option<&T>,
259 ) -> &T {
260 f(self).unwrap()
261 }
262 pub fn get_mut<T>(
263 &mut self,
264 f: impl ::std::ops::FnOnce(&Self) -> ::std::option::Option<&mut T>,
265 ) -> &mut T {
266 f(self).unwrap()
267 }
268 pub fn remove<T>(
269 &self,
270 f: impl ::std::ops::FnOnce(&Self) -> ::std::option::Option<T>,
271 ) -> T {
272 f(self).unwrap()
273 }
274 pub fn into_filter<NewF>(self) -> $name<NewF>
275 where
276 F: card_game::identifications::FilterSupertype<NewF>,
277 {
278 $name(self.0, ::std::marker::PhantomData::default())
279 }
280 }
281 impl<F> ::std::convert::From<$name<F>> for $internal_id {
282 fn from(valid_id: $name<F>) -> Self {
283 valid_id.0
284 }
285 }
286 impl<F0, F1> ::std::convert::From<$name<(F0, F1)>> for $name<F0> {
287 fn from(valid_id: $name<(F0, F1)>) -> Self {
288 Self(valid_id.0, ::std::marker::PhantomData::default())
289 }
290 }
291 impl<F0, F1, F2> ::std::convert::From<$name<(F0, F1, F2)>> for $name<(F0, F1)> {
292 fn from(valid_id: $name<(F0, F1, F2)>) -> Self {
293 Self(valid_id.0, ::std::marker::PhantomData::default())
294 }
295 }
296 impl<F0, F1, F2, F3> ::std::convert::From<$name<(F0, F1, F2, F3)>> for $name<(F0, F1, F2)> {
297 fn from(valid_id: $name<(F0, F1, F2, F3)>) -> Self {
298 Self(valid_id.0, ::std::marker::PhantomData::default())
299 }
300 }
301 impl<F0, F1, F2, F3, F4> ::std::convert::From<$name<(F0, F1, F2, F3, F4)>>
302 for $name<(F0, F1, F2, F3)>
303 {
304 fn from(valid_id: $name<(F0, F1, F2, F3, F4)>) -> Self {
305 Self(valid_id.0, ::std::marker::PhantomData::default())
306 }
307 }
308 impl<F0, F1, F2, F3, F4, F5> ::std::convert::From<$name<(F0, F1, F2, F3, F4, F5)>>
309 for $name<(F0, F1, F2, F3, F4)>
310 {
311 fn from(valid_id: $name<(F0, F1, F2, F3, F4, F5)>) -> Self {
312 Self(valid_id.0, ::std::marker::PhantomData::default())
313 }
314 }
315 impl<F0, F1, F2, F3, F4, F5, F6> ::std::convert::From<$name<(F0, F1, F2, F3, F4, F5, F6)>>
316 for $name<(F0, F1, F2, F3, F4, F5)>
317 {
318 fn from(valid_id: $name<(F0, F1, F2, F3, F4, F5, F6)>) -> Self {
319 Self(valid_id.0, ::std::marker::PhantomData::default())
320 }
321 }
322 impl<F0, F1, F2, F3, F4, F5, F6, F7>
323 ::std::convert::From<$name<(F0, F1, F2, F3, F4, F5, F6, F7)>>
324 for $name<(F0, F1, F2, F3, F4, F5, F6)>
325 {
326 fn from(valid_id: $name<(F0, F1, F2, F3, F4, F5, F6, F7)>) -> Self {
327 Self(valid_id.0, ::std::marker::PhantomData::default())
328 }
329 }
330 impl<F0, F1> card_game::identifications::CastTo<$name<F0>> for $name<(F0, F1)> {
331 fn cast_ref(&self) -> &$name<F0> {
332 unsafe { ::std::mem::transmute(self) }
334 }
335 }
336 impl<F0, F1, F2> card_game::identifications::CastTo<$name<(F0, F1)>>
337 for $name<(F0, F1, F2)>
338 {
339 fn cast_ref(&self) -> &$name<(F0, F1)> {
340 unsafe { ::std::mem::transmute(self) }
342 }
343 }
344 impl<F0, F1, F2, F3> card_game::identifications::CastTo<$name<(F0, F1, F2)>>
345 for $name<(F0, F1, F2, F3)>
346 {
347 fn cast_ref(&self) -> &$name<(F0, F1, F2)> {
348 unsafe { ::std::mem::transmute(self) }
350 }
351 }
352
353 impl<F> ::std::cmp::PartialEq for $name<F> {
354 fn eq(&self, other: &Self) -> bool {
355 self.0.eq(&other.0)
356 }
357 }
358 impl<F> ::std::cmp::Eq for $name<F> {}
359 impl<F> ::std::hash::Hash for $name<F> {
360 fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
361 self.0.hash(state)
362 }
363 }
364 };
365}