1use crate::FocusChain;
2use std::fmt::Debug;
3use std::hash::Hash;
4use std::iter;
5use strum::IntoEnumIterator;
6use strum_macros::EnumIter;
7
8pub trait EzCptIds:
10 Default + Eq + PartialEq + IntoEnumIterator + Clone + Hash + Debug + Send + FocusChain + 'static
11{
12}
13
14#[derive(PartialEq, Eq, Clone, Debug, Hash, Default)]
16pub struct NoClientCptId;
17
18impl FocusChain for NoClientCptId {
19 fn after(&self) -> Option<Self> {
20 None
21 }
22
23 fn before(&self) -> Option<Self> {
24 None
25 }
26
27 fn last() -> Option<Self> {
28 None
29 }
30
31 fn first() -> Option<Self> {
32 None
33 }
34}
35impl EzCptIds for NoClientCptId {}
36
37impl IntoEnumIterator for NoClientCptId {
38 type Iterator = iter::Empty<NoClientCptId>;
39
40 fn iter() -> Self::Iterator {
41 iter::empty()
42 }
43}
44
45#[allow(missing_docs)]
47#[derive(Ord, PartialOrd, PartialEq, Eq, Clone, Debug, Hash, EnumIter)]
48pub enum EzCptId<CID>
49where
50 CID: EzCptIds + Default,
51{
52 StateDebugger,
53 LogsViewer,
54 TickIndicator,
55 FrameIndicator,
56 Legends,
57 Client(CID),
58}
59
60impl<CID> Default for EzCptId<CID>
61where
62 CID: EzCptIds,
63{
64 fn default() -> Self {
65 EzCptId::Client(CID::default())
66 }
67}
68
69impl<CID> From<CID> for EzCptId<CID>
70where
71 CID: EzCptIds,
72{
73 fn from(cpt_id: CID) -> Self {
74 Self::Client(cpt_id)
75 }
76}
77
78impl<CID> EzCptIds for EzCptId<CID> where CID: EzCptIds {}
79impl<CID> FocusChain for EzCptId<CID>
80where
81 CID: EzCptIds,
82{
83 fn after(&self) -> Option<Self> {
84 if let EzCptId::Client(cid) = &self
85 && let Some(id) = cid.after()
86 {
87 return Some(EzCptId::Client(id));
88 }
89 let mut iter = Self::iter();
90 while let Some(current) = iter.next() {
91 if ¤t == self {
92 return iter.next();
93 }
94 }
95 None
96 }
97
98 fn before(&self) -> Option<Self> {
99 if let EzCptId::Client(cid) = &self
100 && let Some(id) = cid.before()
101 {
102 return Some(EzCptId::Client(id));
103 }
104 let iter = Self::iter();
105 let mut previous = None;
106 for current in iter {
107 if ¤t == self {
108 return previous;
109 }
110 previous = Some(current);
111 }
112 None
113 }
114 fn last() -> Option<Self> {
115 match Self::iter().next_back() {
116 Some(v) => match v {
117 EzCptId::Client(_cid) => CID::last().map(|v| EzCptId::Client(v)),
118 _ => Some(v),
119 },
120 None => None,
121 }
122 }
123 fn first() -> Option<Self> {
124 match Self::iter().next() {
125 Some(v) => match v {
126 EzCptId::Client(_cid) => CID::first().map(|v| EzCptId::Client(v)),
127 _ => Some(v),
128 },
129 None => None,
130 }
131 }
132}