zerodds_corba_rt/
priority.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct Priority(i16);
10
11pub const MIN_PRIORITY: i16 = 0;
13pub const MAX_PRIORITY: i16 = 32767;
15
16impl Priority {
17 #[must_use]
19 pub fn new(value: i16) -> Option<Self> {
20 if (MIN_PRIORITY..=MAX_PRIORITY).contains(&value) {
21 Some(Self(value))
22 } else {
23 None
24 }
25 }
26
27 #[must_use]
29 pub fn clamped(value: i32) -> Self {
30 Self(value.clamp(MIN_PRIORITY as i32, MAX_PRIORITY as i32) as i16)
31 }
32
33 #[must_use]
35 pub fn value(self) -> i16 {
36 self.0
37 }
38}
39
40pub trait PriorityMapping {
43 fn to_native(&self, corba: Priority) -> Option<i32>;
45 fn to_corba(&self, native: i32) -> Option<Priority>;
47}
48
49#[derive(Debug, Clone, Copy)]
52pub struct LinearPriorityMapping {
53 native_min: i32,
54 native_max: i32,
55}
56
57impl LinearPriorityMapping {
58 #[must_use]
60 pub fn new(native_min: i32, native_max: i32) -> Self {
61 Self {
62 native_min,
63 native_max,
64 }
65 }
66}
67
68impl PriorityMapping for LinearPriorityMapping {
69 fn to_native(&self, corba: Priority) -> Option<i32> {
70 let span = i64::from(self.native_max - self.native_min);
71 let scaled = i64::from(corba.value()) * span / i64::from(MAX_PRIORITY);
72 Some(self.native_min + scaled as i32)
73 }
74
75 fn to_corba(&self, native: i32) -> Option<Priority> {
76 if native < self.native_min || native > self.native_max {
77 return None;
78 }
79 let span = i64::from(self.native_max - self.native_min);
80 if span == 0 {
81 return Priority::new(0);
82 }
83 let scaled = i64::from(native - self.native_min) * i64::from(MAX_PRIORITY) / span;
84 Priority::new(scaled as i16)
85 }
86}
87
88#[cfg(test)]
89#[allow(clippy::unwrap_used, clippy::panic)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn priority_range() {
95 assert!(Priority::new(0).is_some());
96 assert!(Priority::new(32767).is_some());
97 assert!(Priority::new(-1).is_none());
98 assert_eq!(Priority::clamped(99999).value(), 32767);
99 assert_eq!(Priority::clamped(-5).value(), 0);
100 }
101
102 #[test]
103 fn linear_mapping_endpoints() {
104 let m = LinearPriorityMapping::new(1, 99);
105 assert_eq!(m.to_native(Priority::new(0).unwrap()), Some(1));
106 assert_eq!(m.to_native(Priority::new(32767).unwrap()), Some(99)); let mid = m.to_native(Priority::new(16383).unwrap()).unwrap();
109 assert!((49..=51).contains(&mid), "mid={mid}");
110 }
111
112 #[test]
113 fn native_out_of_window_unmapped() {
114 let m = LinearPriorityMapping::new(1, 99);
115 assert!(m.to_corba(0).is_none());
116 assert!(m.to_corba(100).is_none());
117 assert!(m.to_corba(50).is_some());
118 }
119}