openigtlink_rust/protocol/types/
position.rs1use crate::protocol::message::Message;
8use crate::error::{IgtlError, Result};
9use bytes::{Buf, BufMut};
10
11#[derive(Debug, Clone, PartialEq)]
19pub struct PositionMessage {
20 pub position: [f32; 3], pub quaternion: [f32; 4], }
29
30impl PositionMessage {
31 pub fn identity() -> Self {
33 PositionMessage {
34 position: [0.0, 0.0, 0.0],
35 quaternion: [0.0, 0.0, 0.0, 1.0], }
37 }
38
39 pub fn new(x: f32, y: f32, z: f32) -> Self {
41 PositionMessage {
42 position: [x, y, z],
43 quaternion: [0.0, 0.0, 0.0, 1.0],
44 }
45 }
46
47 pub fn with_quaternion(position: [f32; 3], quaternion: [f32; 4]) -> Self {
49 PositionMessage {
50 position,
51 quaternion,
52 }
53 }
54
55 pub fn get_position(&self) -> (f32, f32, f32) {
57 (self.position[0], self.position[1], self.position[2])
58 }
59
60 pub fn get_quaternion(&self) -> (f32, f32, f32, f32) {
62 (
63 self.quaternion[0],
64 self.quaternion[1],
65 self.quaternion[2],
66 self.quaternion[3],
67 )
68 }
69}
70
71impl Message for PositionMessage {
72 fn message_type() -> &'static str {
73 "POSITION"
74 }
75
76 fn encode_content(&self) -> Result<Vec<u8>> {
77 let mut buf = Vec::with_capacity(28);
78
79 for &coord in &self.position {
81 buf.put_f32(coord);
82 }
83
84 for &comp in &self.quaternion {
86 buf.put_f32(comp);
87 }
88
89 Ok(buf)
90 }
91
92 fn decode_content(mut data: &[u8]) -> Result<Self> {
93 if data.len() < 28 {
94 return Err(IgtlError::InvalidSize {
95 expected: 28,
96 actual: data.len(),
97 });
98 }
99
100 let position = [data.get_f32(), data.get_f32(), data.get_f32()];
102
103 let quaternion = [
105 data.get_f32(),
106 data.get_f32(),
107 data.get_f32(),
108 data.get_f32(),
109 ];
110
111 Ok(PositionMessage {
112 position,
113 quaternion,
114 })
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn test_message_type() {
124 assert_eq!(PositionMessage::message_type(), "POSITION");
125 }
126
127 #[test]
128 fn test_identity() {
129 let pos = PositionMessage::identity();
130 assert_eq!(pos.position, [0.0, 0.0, 0.0]);
131 assert_eq!(pos.quaternion, [0.0, 0.0, 0.0, 1.0]);
132 }
133
134 #[test]
135 fn test_new() {
136 let pos = PositionMessage::new(10.0, 20.0, 30.0);
137 assert_eq!(pos.position, [10.0, 20.0, 30.0]);
138 assert_eq!(pos.quaternion, [0.0, 0.0, 0.0, 1.0]);
139 }
140
141 #[test]
142 fn test_with_quaternion() {
143 let pos = PositionMessage::with_quaternion(
144 [1.0, 2.0, 3.0],
145 [0.1, 0.2, 0.3, 0.4],
146 );
147 assert_eq!(pos.position, [1.0, 2.0, 3.0]);
148 assert_eq!(pos.quaternion, [0.1, 0.2, 0.3, 0.4]);
149 }
150
151 #[test]
152 fn test_encode_size() {
153 let pos = PositionMessage::new(1.0, 2.0, 3.0);
154 let encoded = pos.encode_content().unwrap();
155 assert_eq!(encoded.len(), 28);
156 }
157
158 #[test]
159 fn test_position_roundtrip() {
160 let original = PositionMessage::with_quaternion(
161 [100.5, 200.25, 300.125],
162 [0.1, 0.2, 0.3, 0.9274], );
164
165 let encoded = original.encode_content().unwrap();
166 let decoded = PositionMessage::decode_content(&encoded).unwrap();
167
168 assert_eq!(decoded.position, original.position);
169 assert_eq!(decoded.quaternion, original.quaternion);
170 }
171
172 #[test]
173 fn test_big_endian_encoding() {
174 let pos = PositionMessage::new(1.0, 0.0, 0.0);
175 let encoded = pos.encode_content().unwrap();
176
177 assert_eq!(encoded[0], 0x3F);
179 assert_eq!(encoded[1], 0x80);
180 assert_eq!(encoded[2], 0x00);
181 assert_eq!(encoded[3], 0x00);
182 }
183
184 #[test]
185 fn test_decode_invalid_size() {
186 let data = vec![0u8; 20]; let result = PositionMessage::decode_content(&data);
188 assert!(result.is_err());
189 }
190
191 #[test]
192 fn test_get_position() {
193 let pos = PositionMessage::new(10.0, 20.0, 30.0);
194 let (x, y, z) = pos.get_position();
195 assert_eq!((x, y, z), (10.0, 20.0, 30.0));
196 }
197
198 #[test]
199 fn test_get_quaternion() {
200 let pos = PositionMessage::with_quaternion(
201 [0.0, 0.0, 0.0],
202 [0.1, 0.2, 0.3, 0.4],
203 );
204 let (ox, oy, oz, w) = pos.get_quaternion();
205 assert_eq!((ox, oy, oz, w), (0.1, 0.2, 0.3, 0.4));
206 }
207}