zerodds_xrce/
object_kind.rs1use crate::error::XrceError;
17
18pub const OBJK_INVALID: u8 = 0x00;
20pub const OBJK_PARTICIPANT: u8 = 0x01;
22pub const OBJK_TOPIC: u8 = 0x02;
24pub const OBJK_PUBLISHER: u8 = 0x03;
26pub const OBJK_SUBSCRIBER: u8 = 0x04;
28pub const OBJK_DATAWRITER: u8 = 0x05;
30pub const OBJK_DATAREADER: u8 = 0x06;
32pub const OBJK_TYPE: u8 = 0x0A;
34pub const OBJK_QOSPROFILE: u8 = 0x0B;
36pub const OBJK_APPLICATION: u8 = 0x0C;
38pub const OBJK_AGENT: u8 = 0x0D;
40pub const OBJK_CLIENT: u8 = 0x0E;
42pub const OBJK_DOMAIN: u8 = 0x0F;
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
47#[repr(u8)]
48#[allow(missing_docs)]
49pub enum ObjectKind {
50 Invalid = OBJK_INVALID,
51 Participant = OBJK_PARTICIPANT,
52 Topic = OBJK_TOPIC,
53 Publisher = OBJK_PUBLISHER,
54 Subscriber = OBJK_SUBSCRIBER,
55 DataWriter = OBJK_DATAWRITER,
56 DataReader = OBJK_DATAREADER,
57 Type = OBJK_TYPE,
58 QosProfile = OBJK_QOSPROFILE,
59 Application = OBJK_APPLICATION,
60 Agent = OBJK_AGENT,
61 Client = OBJK_CLIENT,
62 Domain = OBJK_DOMAIN,
63}
64
65impl ObjectKind {
66 #[must_use]
68 pub fn to_u8(self) -> u8 {
69 self as u8
70 }
71
72 pub fn from_u8(byte: u8) -> Result<Self, XrceError> {
79 match byte {
80 OBJK_INVALID => Ok(Self::Invalid),
81 OBJK_PARTICIPANT => Ok(Self::Participant),
82 OBJK_TOPIC => Ok(Self::Topic),
83 OBJK_PUBLISHER => Ok(Self::Publisher),
84 OBJK_SUBSCRIBER => Ok(Self::Subscriber),
85 OBJK_DATAWRITER => Ok(Self::DataWriter),
86 OBJK_DATAREADER => Ok(Self::DataReader),
87 OBJK_TYPE => Ok(Self::Type),
88 OBJK_QOSPROFILE => Ok(Self::QosProfile),
89 OBJK_APPLICATION => Ok(Self::Application),
90 OBJK_AGENT => Ok(Self::Agent),
91 OBJK_CLIENT => Ok(Self::Client),
92 OBJK_DOMAIN => Ok(Self::Domain),
93 _ => Err(XrceError::ValueOutOfRange {
94 message: "object kind not in DDS-XRCE spec",
95 }),
96 }
97 }
98
99 #[must_use]
102 pub fn is_endpoint(self) -> bool {
103 matches!(self, Self::DataWriter | Self::DataReader)
104 }
105
106 #[must_use]
109 pub fn is_container(self) -> bool {
110 matches!(self, Self::Publisher | Self::Subscriber | Self::Participant)
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 #![allow(clippy::expect_used, clippy::unwrap_used)]
117 use super::*;
118
119 #[test]
120 fn all_spec_kinds_roundtrip() {
121 for k in [
122 ObjectKind::Invalid,
123 ObjectKind::Participant,
124 ObjectKind::Topic,
125 ObjectKind::Publisher,
126 ObjectKind::Subscriber,
127 ObjectKind::DataWriter,
128 ObjectKind::DataReader,
129 ObjectKind::Type,
130 ObjectKind::QosProfile,
131 ObjectKind::Application,
132 ObjectKind::Agent,
133 ObjectKind::Client,
134 ObjectKind::Domain,
135 ] {
136 assert_eq!(ObjectKind::from_u8(k.to_u8()).unwrap(), k);
137 }
138 }
139
140 #[test]
141 fn unknown_byte_rejected() {
142 assert!(ObjectKind::from_u8(0x07).is_err());
144 assert!(ObjectKind::from_u8(0x10).is_err());
146 assert!(ObjectKind::from_u8(0xFF).is_err());
147 }
148
149 #[test]
150 fn endpoint_classification() {
151 assert!(ObjectKind::DataWriter.is_endpoint());
152 assert!(ObjectKind::DataReader.is_endpoint());
153 assert!(!ObjectKind::Topic.is_endpoint());
154 assert!(!ObjectKind::Participant.is_endpoint());
155 }
156
157 #[test]
158 fn container_classification() {
159 assert!(ObjectKind::Publisher.is_container());
160 assert!(ObjectKind::Subscriber.is_container());
161 assert!(ObjectKind::Participant.is_container());
162 assert!(!ObjectKind::DataWriter.is_container());
163 assert!(!ObjectKind::Topic.is_container());
164 }
165
166 #[test]
167 fn raw_const_values_match_spec() {
168 assert_eq!(OBJK_PARTICIPANT, 0x01);
170 assert_eq!(OBJK_TOPIC, 0x02);
171 assert_eq!(OBJK_DATAWRITER, 0x05);
172 assert_eq!(OBJK_DATAREADER, 0x06);
173 assert_eq!(OBJK_AGENT, 0x0D);
174 assert_eq!(OBJK_CLIENT, 0x0E);
175 }
176}