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, Deserialize, Eq, PartialEq, Serialize)]
13#[serde(deny_unknown_fields)]
14pub struct MemoryManagerIdRange {
15 pub(crate) start: u8,
16 pub(crate) end: u8,
17}
18
19impl MemoryManagerIdRange {
20 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
22 if start > end {
23 return Err(MemoryManagerRangeError::InvalidRange { start, end });
24 }
25 if end == MEMORY_MANAGER_INVALID_ID {
27 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
28 }
29 Ok(Self { start, end })
30 }
31
32 #[must_use]
34 pub const fn all_usable() -> Self {
35 Self {
36 start: MEMORY_MANAGER_MIN_ID,
37 end: MEMORY_MANAGER_MAX_ID,
38 }
39 }
40
41 #[must_use]
43 pub const fn contains(&self, id: u8) -> bool {
44 id >= self.start && id <= self.end
45 }
46
47 pub const fn validate(&self) -> Result<(), MemoryManagerRangeError> {
49 match Self::new(self.start, self.end) {
50 Ok(_) => Ok(()),
51 Err(err) => Err(err),
52 }
53 }
54
55 #[must_use]
57 pub const fn start(&self) -> u8 {
58 self.start
59 }
60
61 #[must_use]
63 pub const fn end(&self) -> u8 {
64 self.end
65 }
66}
67
68#[non_exhaustive]
73#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
74pub enum MemoryManagerRangeError {
75 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
77 InvalidRange {
78 start: u8,
80 end: u8,
82 },
83 #[error("MemoryManager ID {id} is not a usable allocation slot")]
85 InvalidMemoryManagerId {
86 id: u8,
88 },
89}
90
91#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
103pub enum MemoryManagerRangeMode {
104 Reserved,
108 Allowed,
112}
113
114#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
121#[serde(deny_unknown_fields)]
122pub struct MemoryManagerAuthorityRecord {
123 pub(crate) range: MemoryManagerIdRange,
125 pub(crate) authority: String,
127 pub(crate) mode: MemoryManagerRangeMode,
129 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
131 pub(crate) purpose: Option<String>,
132}
133
134impl MemoryManagerAuthorityRecord {
135 pub fn new(
137 range: MemoryManagerIdRange,
138 authority: impl Into<String>,
139 mode: MemoryManagerRangeMode,
140 purpose: Option<String>,
141 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
142 let record = Self {
143 range,
144 authority: authority.into(),
145 mode,
146 purpose,
147 };
148 validate_authority_record(&record)?;
149 Ok(record)
150 }
151
152 #[must_use]
154 pub const fn range(&self) -> MemoryManagerIdRange {
155 self.range
156 }
157
158 #[must_use]
160 pub fn authority(&self) -> &str {
161 &self.authority
162 }
163
164 #[must_use]
166 pub const fn mode(&self) -> MemoryManagerRangeMode {
167 self.mode
168 }
169
170 #[must_use]
172 pub fn purpose(&self) -> Option<&str> {
173 self.purpose.as_deref()
174 }
175
176 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
178 validate_authority_record(self)
179 }
180}
181
182#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
201pub struct MemoryManagerRangeAuthority {
202 authorities: Vec<MemoryManagerAuthorityRecord>,
203}
204
205#[derive(Deserialize)]
206#[serde(deny_unknown_fields)]
207struct MemoryManagerRangeAuthorityDto {
208 authorities: Vec<MemoryManagerAuthorityRecord>,
209}
210
211impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
212 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
213 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
214 Self::from_records(dto.authorities).map_err(D::Error::custom)
215 }
216}
217
218impl MemoryManagerRangeAuthority {
219 #[must_use]
221 pub const fn new() -> Self {
222 Self {
223 authorities: Vec::new(),
224 }
225 }
226
227 pub fn from_records(
233 records: Vec<MemoryManagerAuthorityRecord>,
234 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
235 let mut authorities: Vec<MemoryManagerAuthorityRecord> = Vec::new();
236 for record in records {
237 validate_authority_record(&record)?;
238 let insertion = authorities
239 .partition_point(|existing| existing.range.start() < record.range.start());
240 let neighbours = insertion.saturating_sub(1)..(insertion + 1).min(authorities.len());
243 for existing in &authorities[neighbours] {
244 if ranges_overlap(existing.range, record.range) {
245 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
246 existing_start: existing.range.start(),
247 existing_end: existing.range.end(),
248 candidate_start: record.range.start(),
249 candidate_end: record.range.end(),
250 });
251 }
252 }
253 authorities.insert(insertion, record);
254 }
255 Ok(Self { authorities })
256 }
257
258 pub fn validate_slot_authority(
260 &self,
261 slot: &MemoryManagerSlot,
262 expected_authority: &str,
263 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
264 let id = slot.id();
265 self.validate_id_authority(id, expected_authority)
266 }
267
268 pub fn validate_slot_authority_mode(
270 &self,
271 slot: &MemoryManagerSlot,
272 expected_authority: &str,
273 expected_mode: MemoryManagerRangeMode,
274 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
275 let id = slot.id();
276 self.validate_id_authority_mode(id, expected_authority, expected_mode)
277 }
278
279 pub fn validate_id_authority(
281 &self,
282 id: u8,
283 expected_authority: &str,
284 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
285 validate_diagnostic_string("expected_authority", expected_authority)?;
286 let record = self
287 .authority_for_id(id)?
288 .ok_or(MemoryManagerRangeAuthorityError::UnclaimedId { id })?;
289
290 if record.authority != expected_authority {
291 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
292 id,
293 expected_authority: expected_authority.to_string(),
294 actual_authority: record.authority.clone(),
295 });
296 }
297
298 Ok(record)
299 }
300
301 pub fn validate_id_authority_mode(
303 &self,
304 id: u8,
305 expected_authority: &str,
306 expected_mode: MemoryManagerRangeMode,
307 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
308 let record = self.validate_id_authority(id, expected_authority)?;
309 if record.mode != expected_mode {
310 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
311 id,
312 authority: record.authority.clone(),
313 expected_mode,
314 actual_mode: record.mode,
315 });
316 }
317 Ok(record)
318 }
319
320 pub fn authority_for_id(
322 &self,
323 id: u8,
324 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
325 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
326 let index = self
330 .authorities
331 .partition_point(|record| record.range.end() < id);
332 Ok(self
333 .authorities
334 .get(index)
335 .filter(|record| record.range.start() <= id))
336 }
337
338 #[must_use]
344 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
345 &self.authorities
346 }
347
348 pub fn validate_complete_coverage(
354 &self,
355 target: MemoryManagerIdRange,
356 ) -> Result<(), MemoryManagerRangeAuthorityError> {
357 if self.authorities.is_empty() {
358 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
359 start: target.start(),
360 end: target.end(),
361 });
362 }
363
364 for record in &self.authorities {
365 if record.range.start() < target.start() || record.range.end() > target.end() {
366 return Err(
367 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
368 start: record.range.start(),
369 end: record.range.end(),
370 target_start: target.start(),
371 target_end: target.end(),
372 },
373 );
374 }
375 }
376
377 let mut next_uncovered = target.start();
378 for record in &self.authorities {
379 if record.range.start() > next_uncovered {
380 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
381 start: next_uncovered,
382 end: record.range.start() - 1,
383 });
384 }
385 next_uncovered = record.range.end() + 1;
388 }
389
390 if next_uncovered <= target.end() {
391 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
392 start: next_uncovered,
393 end: target.end(),
394 });
395 }
396
397 Ok(())
398 }
399}
400
401fn validate_authority_record(
402 record: &MemoryManagerAuthorityRecord,
403) -> Result<(), MemoryManagerRangeAuthorityError> {
404 record.range.validate()?;
405 validate_diagnostic_string("authority", &record.authority)?;
406 if let Some(purpose) = &record.purpose {
407 validate_diagnostic_string("purpose", purpose)?;
408 }
409 Ok(())
410}
411
412#[non_exhaustive]
417#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
418pub enum MemoryManagerRangeAuthorityError {
419 #[error(transparent)]
421 Range(#[from] MemoryManagerRangeError),
422 #[error("{0}")]
424 Slot(#[from] MemoryManagerSlotError),
425 #[error(
427 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
428 )]
429 OverlappingRanges {
430 existing_start: u8,
432 existing_end: u8,
434 candidate_start: u8,
436 candidate_end: u8,
438 },
439 #[error("{field} {reason}")]
441 InvalidDiagnosticString {
442 field: &'static str,
444 reason: &'static str,
446 },
447 #[error("MemoryManager ID {id} is not covered by an authority range")]
449 UnclaimedId {
450 id: u8,
452 },
453 #[error(
455 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
456 )]
457 AuthorityMismatch {
458 id: u8,
460 expected_authority: String,
462 actual_authority: String,
464 },
465 #[error(
467 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
468 )]
469 ModeMismatch {
470 id: u8,
472 authority: String,
474 expected_mode: MemoryManagerRangeMode,
476 actual_mode: MemoryManagerRangeMode,
478 },
479 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
481 MissingCoverage {
482 start: u8,
484 end: u8,
486 },
487 #[error(
489 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
490 )]
491 RangeOutsideCoverageTarget {
492 start: u8,
494 end: u8,
496 target_start: u8,
498 target_end: u8,
500 },
501}
502
503const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
504 left.start() <= right.end() && right.start() <= left.end()
505}
506
507fn validate_diagnostic_string(
508 field: &'static str,
509 value: &str,
510) -> Result<(), MemoryManagerRangeAuthorityError> {
511 validate_diagnostic_text(value).map_err(|error| {
512 MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
513 field,
514 reason: error.reason(),
515 }
516 })
517}