zerodds_qos/policies/
presentation.rs1use zerodds_cdr::{BufferReader, BufferWriter, DecodeError, EncodeError};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
15#[repr(u32)]
16pub enum PresentationAccessScope {
17 #[default]
19 Instance = 0,
20 Topic = 1,
22 Group = 2,
24}
25
26impl PresentationAccessScope {
27 #[must_use]
29 pub const fn try_from_u32(v: u32) -> Option<Self> {
30 match v {
31 0 => Some(Self::Instance),
32 1 => Some(Self::Topic),
33 2 => Some(Self::Group),
34 _ => None,
35 }
36 }
37
38 #[must_use]
40 pub const fn from_u32(v: u32) -> Self {
41 match v {
42 1 => Self::Topic,
43 2 => Self::Group,
44 _ => Self::Instance,
45 }
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
51pub struct PresentationQosPolicy {
52 pub access_scope: PresentationAccessScope,
54 pub coherent_access: bool,
56 pub ordered_access: bool,
58}
59
60impl PresentationQosPolicy {
61 pub fn encode_into(self, w: &mut BufferWriter) -> Result<(), EncodeError> {
66 w.write_u32(self.access_scope as u32)?;
67 w.write_u8(u8::from(self.coherent_access))?;
68 w.write_u8(u8::from(self.ordered_access))?;
69 w.write_u8(0)?;
71 w.write_u8(0)
72 }
73
74 pub fn decode_from(r: &mut BufferReader<'_>) -> Result<Self, DecodeError> {
79 let v = r.read_u32()?;
80 let access_scope =
81 PresentationAccessScope::try_from_u32(v).ok_or(DecodeError::InvalidEnum {
82 kind: "PresentationAccessScope",
83 value: v,
84 })?;
85 let coherent_access = r.read_u8()? != 0;
86 let ordered_access = r.read_u8()? != 0;
87 let _pad1 = r.read_u8()?;
88 let _pad2 = r.read_u8()?;
89 Ok(Self {
90 access_scope,
91 coherent_access,
92 ordered_access,
93 })
94 }
95}
96
97#[cfg(test)]
98#[allow(clippy::unwrap_used)]
99mod tests {
100 use super::*;
101 use zerodds_cdr::Endianness;
102
103 #[test]
104 fn default_instance_no_flags() {
105 let d = PresentationQosPolicy::default();
106 assert_eq!(d.access_scope, PresentationAccessScope::Instance);
107 assert!(!d.coherent_access);
108 assert!(!d.ordered_access);
109 }
110
111 #[test]
112 fn scope_ordering() {
113 use PresentationAccessScope::*;
114 assert!(Instance < Topic);
115 assert!(Topic < Group);
116 }
117
118 #[test]
119 fn try_from_u32_strict() {
120 assert_eq!(
121 PresentationAccessScope::try_from_u32(0),
122 Some(PresentationAccessScope::Instance)
123 );
124 assert_eq!(
125 PresentationAccessScope::try_from_u32(2),
126 Some(PresentationAccessScope::Group)
127 );
128 assert_eq!(PresentationAccessScope::try_from_u32(5), None);
129 }
130
131 #[test]
132 fn from_u32_forward_compat() {
133 assert_eq!(
134 PresentationAccessScope::from_u32(99),
135 PresentationAccessScope::Instance
136 );
137 assert_eq!(
138 PresentationAccessScope::from_u32(1),
139 PresentationAccessScope::Topic
140 );
141 }
142
143 #[test]
144 fn roundtrip_instance_no_flags() {
145 let p = PresentationQosPolicy::default();
146 let mut w = BufferWriter::new(Endianness::Little);
147 p.encode_into(&mut w).unwrap();
148 let bytes = w.into_bytes();
149 let mut r = BufferReader::new(&bytes, Endianness::Little);
150 assert_eq!(PresentationQosPolicy::decode_from(&mut r).unwrap(), p);
151 }
152
153 #[test]
154 fn roundtrip_all_flags() {
155 let p = PresentationQosPolicy {
156 access_scope: PresentationAccessScope::Group,
157 coherent_access: true,
158 ordered_access: true,
159 };
160 let mut w = BufferWriter::new(Endianness::Little);
161 p.encode_into(&mut w).unwrap();
162 let bytes = w.into_bytes();
163 assert_eq!(bytes.len(), 8);
164 let mut r = BufferReader::new(&bytes, Endianness::Little);
165 assert_eq!(PresentationQosPolicy::decode_from(&mut r).unwrap(), p);
166 }
167}