1use super::memory_manager::{
2 MEMORY_MANAGER_INVALID_ID, MEMORY_MANAGER_MAX_ID, MEMORY_MANAGER_MIN_ID, MemoryManagerSlot,
3 MemoryManagerSlotError, validate_memory_manager_id,
4};
5use crate::text::validate_diagnostic_text;
6use serde::{Deserialize, Deserializer, Serialize, de::Error as _};
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
16pub struct MemoryManagerIdRange {
17 start: u8,
18 end: u8,
19}
20
21impl<'de> Deserialize<'de> for MemoryManagerIdRange {
22 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
23 #[derive(Deserialize)]
24 #[serde(rename = "MemoryManagerIdRange", deny_unknown_fields)]
25 struct Bounds {
26 start: u8,
27 end: u8,
28 }
29
30 let bounds = Bounds::deserialize(deserializer)?;
31 Self::new(bounds.start, bounds.end).map_err(D::Error::custom)
32 }
33}
34
35impl MemoryManagerIdRange {
36 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
38 if start > end {
39 return Err(MemoryManagerRangeError::InvalidRange { start, end });
40 }
41 if end == MEMORY_MANAGER_INVALID_ID {
43 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
44 }
45 Ok(Self { start, end })
46 }
47
48 #[must_use]
50 pub const fn all_usable() -> Self {
51 Self {
52 start: MEMORY_MANAGER_MIN_ID,
53 end: MEMORY_MANAGER_MAX_ID,
54 }
55 }
56
57 #[must_use]
59 pub const fn contains(&self, id: u8) -> bool {
60 id >= self.start && id <= self.end
61 }
62
63 #[must_use]
65 pub const fn start(&self) -> u8 {
66 self.start
67 }
68
69 #[must_use]
71 pub const fn end(&self) -> u8 {
72 self.end
73 }
74}
75
76#[non_exhaustive]
81#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
82pub enum MemoryManagerRangeError {
83 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
85 InvalidRange {
86 start: u8,
88 end: u8,
90 },
91 #[error("MemoryManager ID {id} is not a usable allocation slot")]
93 InvalidMemoryManagerId {
94 id: u8,
96 },
97}
98
99#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
111pub enum MemoryManagerRangeMode {
112 Reserved,
116 Allowed,
120}
121
122#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
132pub struct MemoryManagerAuthorityRecord {
133 pub(crate) range: MemoryManagerIdRange,
135 pub(crate) authority: String,
137 pub(crate) mode: MemoryManagerRangeMode,
139 pub(crate) purpose: Option<String>,
141}
142
143impl<'de> Deserialize<'de> for MemoryManagerAuthorityRecord {
144 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
145 #[derive(Deserialize)]
146 #[serde(rename = "MemoryManagerAuthorityRecord", deny_unknown_fields)]
147 struct Record {
148 range: MemoryManagerIdRange,
149 authority: String,
150 mode: MemoryManagerRangeMode,
151 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
152 purpose: Option<String>,
153 }
154
155 let record = Record::deserialize(deserializer)?;
156 Self::new(record.range, record.authority, record.mode, record.purpose)
157 .map_err(D::Error::custom)
158 }
159}
160
161impl MemoryManagerAuthorityRecord {
162 pub fn new(
164 range: MemoryManagerIdRange,
165 authority: impl Into<String>,
166 mode: MemoryManagerRangeMode,
167 purpose: Option<String>,
168 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
169 let authority = authority.into();
170 validate_diagnostic_string("authority", &authority)?;
171 if let Some(purpose) = &purpose {
172 validate_diagnostic_string("purpose", purpose)?;
173 }
174 Ok(Self {
175 range,
176 authority,
177 mode,
178 purpose,
179 })
180 }
181
182 #[must_use]
184 pub const fn range(&self) -> MemoryManagerIdRange {
185 self.range
186 }
187
188 #[must_use]
190 pub fn authority(&self) -> &str {
191 &self.authority
192 }
193
194 #[must_use]
196 pub const fn mode(&self) -> MemoryManagerRangeMode {
197 self.mode
198 }
199
200 #[must_use]
202 pub fn purpose(&self) -> Option<&str> {
203 self.purpose.as_deref()
204 }
205}
206
207#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
226pub struct MemoryManagerRangeAuthority {
227 authorities: Vec<MemoryManagerAuthorityRecord>,
228}
229
230#[derive(Deserialize)]
231#[serde(deny_unknown_fields)]
232struct MemoryManagerRangeAuthorityDto {
233 authorities: Vec<MemoryManagerAuthorityRecord>,
234}
235
236impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
237 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
238 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
239 Self::from_records(dto.authorities).map_err(D::Error::custom)
240 }
241}
242
243impl MemoryManagerRangeAuthority {
244 #[must_use]
246 pub const fn new() -> Self {
247 Self {
248 authorities: Vec::new(),
249 }
250 }
251
252 pub fn from_records(
258 mut records: Vec<MemoryManagerAuthorityRecord>,
259 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
260 for index in 0..records.len() {
261 let record = &records[index];
262 let accepted = &records[..index];
263 let insertion =
264 accepted.partition_point(|existing| existing.range.start() < record.range.start());
265 let neighbours = insertion.saturating_sub(1)..(insertion + 1).min(accepted.len());
268 for existing in &accepted[neighbours] {
269 if ranges_overlap(existing.range, record.range) {
270 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
271 existing_start: existing.range.start(),
272 existing_end: existing.range.end(),
273 candidate_start: record.range.start(),
274 candidate_end: record.range.end(),
275 });
276 }
277 }
278 records[insertion..=index].rotate_right(1);
281 }
282 Ok(Self {
283 authorities: records,
284 })
285 }
286
287 pub fn validate_slot_authority(
289 &self,
290 slot: &MemoryManagerSlot,
291 expected_authority: &str,
292 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
293 let id = slot.id();
294 self.validate_id_authority(id, expected_authority)
295 }
296
297 pub fn validate_slot_authority_mode(
299 &self,
300 slot: &MemoryManagerSlot,
301 expected_authority: &str,
302 expected_mode: MemoryManagerRangeMode,
303 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
304 let id = slot.id();
305 self.validate_id_authority_mode(id, expected_authority, expected_mode)
306 }
307
308 pub fn validate_id_authority(
310 &self,
311 id: u8,
312 expected_authority: &str,
313 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
314 validate_diagnostic_string("expected_authority", expected_authority)?;
315 let record = self
316 .authority_for_id(id)?
317 .ok_or(MemoryManagerRangeAuthorityError::UnclaimedId { id })?;
318
319 if record.authority != expected_authority {
320 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
321 id,
322 expected_authority: expected_authority.to_string(),
323 actual_authority: record.authority.clone(),
324 });
325 }
326
327 Ok(record)
328 }
329
330 pub fn validate_id_authority_mode(
332 &self,
333 id: u8,
334 expected_authority: &str,
335 expected_mode: MemoryManagerRangeMode,
336 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
337 let record = self.validate_id_authority(id, expected_authority)?;
338 if record.mode != expected_mode {
339 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
340 id,
341 authority: record.authority.clone(),
342 expected_mode,
343 actual_mode: record.mode,
344 });
345 }
346 Ok(record)
347 }
348
349 pub fn authority_for_id(
351 &self,
352 id: u8,
353 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
354 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
355 let index = self
359 .authorities
360 .partition_point(|record| record.range.end() < id);
361 Ok(self
362 .authorities
363 .get(index)
364 .filter(|record| record.range.start() <= id))
365 }
366
367 #[must_use]
373 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
374 &self.authorities
375 }
376
377 pub fn validate_complete_coverage(
383 &self,
384 target: MemoryManagerIdRange,
385 ) -> Result<(), MemoryManagerRangeAuthorityError> {
386 if self.authorities.is_empty() {
387 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
388 start: target.start(),
389 end: target.end(),
390 });
391 }
392
393 for record in &self.authorities {
394 if record.range.start() < target.start() || record.range.end() > target.end() {
395 return Err(
396 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
397 start: record.range.start(),
398 end: record.range.end(),
399 target_start: target.start(),
400 target_end: target.end(),
401 },
402 );
403 }
404 }
405
406 let mut next_uncovered = target.start();
407 for record in &self.authorities {
408 if record.range.start() > next_uncovered {
409 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
410 start: next_uncovered,
411 end: record.range.start() - 1,
412 });
413 }
414 next_uncovered = record.range.end() + 1;
417 }
418
419 if next_uncovered <= target.end() {
420 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
421 start: next_uncovered,
422 end: target.end(),
423 });
424 }
425
426 Ok(())
427 }
428}
429
430#[non_exhaustive]
435#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
436pub enum MemoryManagerRangeAuthorityError {
437 #[error(transparent)]
439 Range(#[from] MemoryManagerRangeError),
440 #[error("{0}")]
442 Slot(#[from] MemoryManagerSlotError),
443 #[error(
445 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
446 )]
447 OverlappingRanges {
448 existing_start: u8,
450 existing_end: u8,
452 candidate_start: u8,
454 candidate_end: u8,
456 },
457 #[error("{field} {reason}")]
459 InvalidDiagnosticString {
460 field: &'static str,
462 reason: &'static str,
464 },
465 #[error("MemoryManager ID {id} is not covered by an authority range")]
467 UnclaimedId {
468 id: u8,
470 },
471 #[error(
473 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
474 )]
475 AuthorityMismatch {
476 id: u8,
478 expected_authority: String,
480 actual_authority: String,
482 },
483 #[error(
485 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
486 )]
487 ModeMismatch {
488 id: u8,
490 authority: String,
492 expected_mode: MemoryManagerRangeMode,
494 actual_mode: MemoryManagerRangeMode,
496 },
497 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
499 MissingCoverage {
500 start: u8,
502 end: u8,
504 },
505 #[error(
507 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
508 )]
509 RangeOutsideCoverageTarget {
510 start: u8,
512 end: u8,
514 target_start: u8,
516 target_end: u8,
518 },
519}
520
521const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
522 left.start() <= right.end() && right.start() <= left.end()
523}
524
525fn validate_diagnostic_string(
526 field: &'static str,
527 value: &str,
528) -> Result<(), MemoryManagerRangeAuthorityError> {
529 validate_diagnostic_text(value).map_err(|error| {
530 MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
531 field,
532 reason: error.reason(),
533 }
534 })
535}