1use crate::borrow::Mutability;
4use crate::scheduler::{AsLabel, Label};
5use crate::storage::StorageId;
6use crate::ShipHashMap;
7use alloc::borrow::Cow;
8use alloc::boxed::Box;
9use alloc::string::String;
10use alloc::vec::Vec;
11use core::any::TypeId;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
18pub struct WorkloadInfo {
19 #[allow(missing_docs)]
20 pub name: String,
21 #[allow(missing_docs)]
22 pub batches_info: Vec<BatchInfo>,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
29#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
30pub struct BatchInfo {
31 #[allow(missing_docs)]
32 pub systems: (Option<SystemInfo>, Vec<SystemInfo>),
33}
34
35impl BatchInfo {
36 pub fn systems(&self) -> impl Iterator<Item = &'_ SystemInfo> {
38 self.systems.0.iter().chain(&self.systems.1)
39 }
40}
41
42#[derive(Clone, PartialEq, Eq)]
44#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
45pub struct SystemInfo {
46 #[allow(missing_docs)]
47 pub name: String,
48 #[allow(missing_docs)]
49 pub borrow: Vec<TypeInfo>,
50 pub conflict: Option<Conflict>,
52 pub after: Vec<usize>,
54 pub after_all: Vec<BeforeAfterConstraint>,
56 pub before_all: Vec<BeforeAfterConstraint>,
58 pub unique_id: usize,
60}
61
62impl core::fmt::Debug for SystemInfo {
63 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
64 f.debug_struct("SystemInfo")
65 .field("name", &self.name)
66 .field("unique_id", &self.unique_id)
67 .field("borrow", &self.borrow)
68 .field("conflict", &self.conflict)
69 .field("after", &self.after)
70 .field("after_all", &self.after_all)
71 .field("before_all", &self.before_all)
72 .finish()
73 }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq)]
78#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
79pub enum Conflict {
80 Borrow {
82 #[allow(missing_docs)]
83 type_info: TypeInfo,
84 #[allow(missing_docs)]
85 other_system: usize,
86 #[allow(missing_docs)]
87 other_type_info: TypeInfo,
88 },
89 NotSendSync(TypeInfo),
91 OtherNotSendSync {
93 #[allow(missing_docs)]
94 system: usize,
95 #[allow(missing_docs)]
96 type_info: TypeInfo,
97 },
98}
99
100#[derive(Clone, Eq)]
102#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
103pub struct TypeInfo {
104 #[allow(missing_docs)]
105 pub name: Cow<'static, str>,
106 #[allow(missing_docs)]
107 pub mutability: Mutability,
108 #[allow(missing_docs)]
109 #[cfg_attr(feature = "serde1", serde(skip))]
110 pub storage_id: StorageId,
111 #[allow(missing_docs)]
112 pub thread_safe: bool,
113}
114
115impl PartialEq for TypeInfo {
116 fn eq(&self, rhs: &Self) -> bool {
117 self.storage_id == rhs.storage_id && self.mutability == rhs.mutability
118 }
119}
120
121impl PartialEq<(TypeId, Mutability)> for TypeInfo {
122 fn eq(&self, rhs: &(TypeId, Mutability)) -> bool {
123 self.storage_id == rhs.0 && self.mutability == rhs.1
124 }
125}
126
127impl PartialOrd for TypeInfo {
128 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
129 Some(self.cmp(other))
130 }
131}
132
133impl Ord for TypeInfo {
134 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
135 match self.storage_id.cmp(&other.storage_id) {
136 core::cmp::Ordering::Equal => {}
137 ord => return ord,
138 }
139 self.mutability.cmp(&other.mutability)
140 }
141}
142
143impl core::fmt::Debug for TypeInfo {
144 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
145 let mut debug_struct = f.debug_struct("TypeInfo");
146
147 debug_struct
148 .field("name", &self.name)
149 .field("mutability", &self.mutability)
150 .field("thread_safe", &self.thread_safe)
151 .finish()
152 }
153}
154
155impl core::hash::Hash for TypeInfo {
156 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
157 self.storage_id.hash(state);
158 self.mutability.hash(state);
159 }
160}
161
162#[derive(Default, Debug, PartialEq, Eq)]
164#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
165pub struct WorkloadsInfo(pub ShipHashMap<String, WorkloadInfo>);
166
167impl WorkloadsInfo {
168 pub fn new() -> WorkloadsInfo {
170 WorkloadsInfo(ShipHashMap::new())
171 }
172}
173
174#[derive(Clone, Debug, Default)]
177pub struct DedupedLabels(Vec<Box<dyn Label>>);
178
179impl DedupedLabels {
180 pub(crate) fn new() -> DedupedLabels {
181 DedupedLabels(Vec::new())
182 }
183
184 pub(crate) fn with_capacity(capacity: usize) -> DedupedLabels {
185 DedupedLabels(Vec::with_capacity(capacity))
186 }
187
188 pub(crate) fn add<T>(&mut self, label: impl AsLabel<T>) -> bool {
190 let label = label.as_label();
191
192 if !self.0.contains(&label) {
194 self.0.push(label);
195
196 true
197 } else {
198 false
199 }
200 }
201
202 pub(crate) fn is_empty(&self) -> bool {
203 self.0.is_empty()
204 }
205
206 pub(crate) fn iter(&self) -> RequirementsIter<'_> {
207 self.into_iter()
208 }
209
210 pub(crate) fn clear(&mut self) {
211 self.0.clear();
212 }
213
214 pub(crate) fn retain<F: FnMut(&Box<dyn Label>) -> bool>(&mut self, f: F) {
215 self.0.retain(f);
216 }
217}
218
219impl IntoIterator for DedupedLabels {
220 type Item = Box<dyn Label>;
221 type IntoIter = alloc::vec::IntoIter<Self::Item>;
222
223 fn into_iter(self) -> Self::IntoIter {
224 self.0.into_iter()
225 }
226}
227
228impl<'a> IntoIterator for &'a DedupedLabels {
229 type Item = &'a Box<dyn Label>;
230 type IntoIter = RequirementsIter<'a>;
231
232 fn into_iter(self) -> Self::IntoIter {
233 RequirementsIter(self.0.iter())
234 }
235}
236
237pub struct RequirementsIter<'a>(core::slice::Iter<'a, Box<dyn Label>>);
239
240impl<'a> Iterator for RequirementsIter<'a> {
241 type Item = &'a Box<dyn Label>;
242
243 fn next(&mut self) -> Option<Self::Item> {
244 self.0.next()
245 }
246}
247
248impl Extend<Box<dyn Label>> for DedupedLabels {
249 fn extend<T: IntoIterator<Item = Box<dyn Label>>>(&mut self, iter: T) {
250 for label in iter {
251 self.add(label);
252 }
253 }
254}
255
256impl<'a> Extend<&'a Box<dyn Label>> for DedupedLabels {
257 fn extend<T: IntoIterator<Item = &'a Box<dyn Label>>>(&mut self, iter: T) {
258 for label in iter {
259 self.add(label.clone());
260 }
261 }
262}
263
264#[derive(Clone, PartialEq, Eq, Debug)]
266#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
267pub struct BeforeAfterConstraint {
268 #[allow(missing_docs)]
269 pub other_system: usize,
270 #[allow(missing_docs)]
271 pub constraint: String,
272}