openigtlink_rust/lib.rs
1//! OpenIGTLink Protocol Implementation in Rust
2//!
3//! This library provides a Rust implementation of the OpenIGTLink protocol,
4//! which is an open network protocol for image-guided therapy environments.
5//!
6//! # Features
7//!
8//! - **Type-safe message handling** - Leverages Rust's type system for protocol correctness
9//! - **Comprehensive message types** - 21 message types fully implemented
10//! - **Synchronous and asynchronous I/O** - Works with both sync and async Rust
11//! - **Full protocol compliance** - OpenIGTLink Version 2 and 3
12//! - **Memory safe** - No buffer overflows or memory leaks
13//! - **Zero-copy parsing** - Efficient deserialization where possible
14//!
15//! # Quick Start
16//!
17//! ## Basic Client-Server Example
18//!
19//! **Server:**
20//! ```no_run
21//! use openigtlink_rust::io::IgtlServer;
22//! use openigtlink_rust::protocol::types::StatusMessage;
23//!
24//! let server = IgtlServer::bind("127.0.0.1:18944")?;
25//! let mut client_conn = server.accept()?;
26//!
27//! let status = StatusMessage::ok("Server ready");
28//! client_conn.send(&status)?;
29//! # Ok::<(), openigtlink_rust::IgtlError>(())
30//! ```
31//!
32//! **Client:**
33//! ```no_run
34//! use openigtlink_rust::io::IgtlClient;
35//! use openigtlink_rust::protocol::types::TransformMessage;
36//!
37//! let mut client = IgtlClient::connect("127.0.0.1:18944")?;
38//!
39//! let transform = TransformMessage::identity();
40//! client.send(&transform)?;
41//!
42//! let response = client.receive()?;
43//! # Ok::<(), openigtlink_rust::IgtlError>(())
44//! ```
45//!
46//! ## Sending Medical Images
47//!
48//! ```no_run
49//! use openigtlink_rust::protocol::types::{ImageMessage, ScalarType};
50//! use openigtlink_rust::io::IgtlClient;
51//!
52//! let mut client = IgtlClient::connect("127.0.0.1:18944")?;
53//!
54//! let mut image = ImageMessage::new();
55//! image.set_dimensions([512, 512, 1]);
56//! image.set_scalar_type(ScalarType::Uint8);
57//! image.set_image_data(vec![0u8; 512 * 512]);
58//!
59//! client.send(&image)?;
60//! # Ok::<(), openigtlink_rust::IgtlError>(())
61//! ```
62//!
63//! # Architecture
64//!
65//! The library is organized into three main modules:
66//!
67//! ## Module Structure
68//!
69//! - **`protocol`** - Core protocol implementation
70//! - `header` - OpenIGTLink message header (58 bytes)
71//! - `types` - All 21 message type implementations
72//! - `crc` - CRC-64 checksum validation
73//!
74//! - **`io`** - Network I/O layer
75//! - `IgtlClient` - TCP client for sending/receiving messages
76//! - `IgtlServer` - TCP server for accepting connections
77//!
78//! - **`error`** - Error handling
79//! - `IgtlError` - Unified error type for all operations
80//! - `Result<T>` - Type alias for `Result<T, IgtlError>`
81//!
82//! ## Design Principles
83//!
84//! 1. **Type Safety**: Each message type is a distinct Rust type
85//! 2. **Zero-cost Abstractions**: Minimal runtime overhead
86//! 3. **Explicit Error Handling**: All network and parsing errors are explicit
87//! 4. **Protocol Compliance**: Strict adherence to OpenIGTLink specification
88//!
89//! # Supported Message Types
90//!
91//! This implementation includes all major OpenIGTLink message types:
92//!
93//! - **Transform & Tracking**: TRANSFORM, POSITION, QTDATA, TDATA
94//! - **Medical Imaging**: IMAGE, IMGMETA, LBMETA, COLORTABLE
95//! - **Geometric Data**: POINT, POLYDATA, TRAJECTORY
96//! - **Sensor Data**: SENSOR, NDARRAY
97//! - **Communication**: STATUS, CAPABILITY, STRING, COMMAND, BIND
98//! - **Video Streaming**: VIDEO, VIDEOMETA
99//!
100//! # Choosing Message Types
101//!
102//! ## Transform & Tracking
103//!
104//! - **TRANSFORM** - Single 4x4 homogeneous transformation matrix
105//! - Use for: Robot end-effector pose, single tool tracking
106//! - Example: Surgical instrument position
107//!
108//! - **TDATA** - Array of transformation matrices with names
109//! - Use for: Multiple tracking tools simultaneously
110//! - Example: Tracking 5 surgical instruments at once
111//!
112//! - **POSITION** - 3D position only (no orientation)
113//! - Use for: Point cloud data, simplified tracking
114//! - Example: Marker positions without rotation
115//!
116//! - **QTDATA** - Position + Quaternion (alternative to TRANSFORM)
117//! - Use for: More compact rotation representation
118//! - Example: IMU sensor orientation
119//!
120//! ## Medical Imaging
121//!
122//! - **IMAGE** - 2D/3D medical image with metadata
123//! - Use for: CT, MRI, ultrasound images
124//! - Supports: 8/16-bit grayscale, RGB, RGBA
125//! - Example: Real-time ultrasound streaming
126//!
127//! - **VIDEO** - Real-time video frames
128//! - Use for: Endoscopic video, webcam feeds
129//! - Supports: MJPEG, H.264, raw formats
130//! - Example: Laparoscopic camera feed
131//!
132//! - **IMGMETA** - Metadata for multiple images
133//! - Use for: Image catalog, DICOM series info
134//! - Example: List of available CT slices
135//!
136//! ## Sensor Data
137//!
138//! - **SENSOR** - Multi-channel sensor readings
139//! - Use for: Force sensors, temperature arrays
140//! - Example: 6-axis force/torque sensor
141//!
142//! - **NDARRAY** - N-dimensional array data
143//! - Use for: Generic numerical data
144//! - Example: Spectrogram, multi-dimensional measurements
145//!
146//! ## Geometric Data
147//!
148//! - **POINT** - Collection of 3D points with attributes
149//! - Use for: Fiducial markers, anatomical landmarks
150//! - Example: Registration points for navigation
151//!
152//! - **POLYDATA** - 3D mesh with vertices and polygons
153//! - Use for: Organ surfaces, tumor boundaries
154//! - Example: Liver segmentation mesh
155//!
156//! - **TRAJECTORY** - Planned surgical paths
157//! - Use for: Needle insertion paths, biopsy planning
158//! - Example: Brain biopsy trajectory
159//!
160//! ## Communication
161//!
162//! - **STATUS** - Status/error messages
163//! - Use for: Operation success/failure notifications
164//! - Example: "Registration completed successfully"
165//!
166//! - **STRING** - Text messages
167//! - Use for: Logging, user messages
168//! - Example: "Patient positioned, ready to scan"
169//!
170//! - **COMMAND** - Remote procedure calls
171//! - Use for: Controlling remote devices
172//! - Example: "StartScanning", "StopMotor"
173//!
174//! # Examples
175//!
176//! ## Example 1: Sending Transform Data
177//!
178//! ```no_run
179//! use openigtlink_rust::io::IgtlClient;
180//! use openigtlink_rust::protocol::types::TransformMessage;
181//!
182//! let mut client = IgtlClient::connect("192.168.1.100:18944")?;
183//!
184//! // Create transformation matrix (4x4)
185//! let mut transform = TransformMessage::identity();
186//! transform.set_device_name("RobotArm");
187//!
188//! // Set translation (in mm)
189//! transform.matrix[0][3] = 100.0; // X
190//! transform.matrix[1][3] = 50.0; // Y
191//! transform.matrix[2][3] = 200.0; // Z
192//!
193//! // Send to server
194//! client.send(&transform)?;
195//! # Ok::<(), openigtlink_rust::IgtlError>(())
196//! ```
197//!
198//! ## Example 2: Streaming Medical Images
199//!
200//! ```no_run
201//! use openigtlink_rust::io::IgtlClient;
202//! use openigtlink_rust::protocol::types::{ImageMessage, ScalarType};
203//!
204//! let mut client = IgtlClient::connect("localhost:18944")?;
205//!
206//! // Simulate ultrasound image stream (640x480 grayscale)
207//! for frame_num in 0..100 {
208//! let mut image = ImageMessage::new();
209//! image.set_device_name("UltrasoundProbe");
210//! image.set_dimensions([640, 480, 1]);
211//! image.set_scalar_type(ScalarType::Uint8);
212//! image.set_spacing([0.1, 0.1, 1.0]); // mm per pixel
213//!
214//! // Generate synthetic image data
215//! let image_data = vec![((frame_num % 256) as u8); 640 * 480];
216//! image.set_image_data(image_data);
217//!
218//! client.send(&image)?;
219//! std::thread::sleep(std::time::Duration::from_millis(33)); // ~30 fps
220//! }
221//! # Ok::<(), openigtlink_rust::IgtlError>(())
222//! ```
223//!
224//! ## Example 3: Multi-Channel Sensor Data
225//!
226//! ```no_run
227//! use openigtlink_rust::io::IgtlClient;
228//! use openigtlink_rust::protocol::types::SensorMessage;
229//!
230//! let mut client = IgtlClient::connect("localhost:18944")?;
231//!
232//! // 6-axis force/torque sensor
233//! let mut sensor = SensorMessage::new();
234//! sensor.set_device_name("ForceSensor");
235//!
236//! // Forces (Fx, Fy, Fz) and Torques (Tx, Ty, Tz)
237//! let readings = vec![1.2, -0.5, 3.8, 0.1, 0.05, -0.2];
238//! sensor.set_data(readings);
239//! sensor.set_unit(0x0101); // Newton (force) + Newton-meter (torque)
240//!
241//! client.send(&sensor)?;
242//! # Ok::<(), openigtlink_rust::IgtlError>(())
243//! ```
244//!
245//! ## Example 4: Status Message Handling
246//!
247//! ```no_run
248//! use openigtlink_rust::io::IgtlServer;
249//! use openigtlink_rust::protocol::types::StatusMessage;
250//!
251//! let server = IgtlServer::bind("0.0.0.0:18944")?;
252//! let mut client_conn = server.accept()?;
253//!
254//! // Receive message
255//! let message = client_conn.receive()?;
256//!
257//! // Send acknowledgment
258//! let status = StatusMessage::ok("Data received successfully");
259//! client_conn.send(&status)?;
260//! # Ok::<(), openigtlink_rust::IgtlError>(())
261//! ```
262//!
263//! ## Example 5: Error Handling and Recovery
264//!
265//! ```no_run
266//! use openigtlink_rust::io::IgtlClient;
267//! use openigtlink_rust::protocol::types::TransformMessage;
268//! use openigtlink_rust::IgtlError;
269//!
270//! fn send_with_retry(addr: &str) -> Result<(), IgtlError> {
271//! let max_retries = 3;
272//!
273//! for attempt in 0..max_retries {
274//! match IgtlClient::connect(addr) {
275//! Ok(mut client) => {
276//! let transform = TransformMessage::identity();
277//! return client.send(&transform);
278//! }
279//! Err(e) if attempt < max_retries - 1 => {
280//! eprintln!("Connection failed (attempt {}): {}", attempt + 1, e);
281//! std::thread::sleep(std::time::Duration::from_secs(1));
282//! continue;
283//! }
284//! Err(e) => return Err(e),
285//! }
286//! }
287//! unreachable!()
288//! }
289//! # Ok::<(), openigtlink_rust::IgtlError>(())
290//! ```
291//!
292//! # Error Handling
293//!
294//! All operations return `Result<T, IgtlError>`. Common error types:
295//!
296//! - **IoError** - Network communication failures
297//! - **InvalidHeader** - Malformed message headers
298//! - **CrcMismatch** - Data corruption detected
299//! - **UnsupportedMessage** - Unknown message type
300//! - **InvalidData** - Invalid message body
301//!
302//! ```no_run
303//! use openigtlink_rust::io::IgtlClient;
304//! use openigtlink_rust::IgtlError;
305//!
306//! match IgtlClient::connect("localhost:18944") {
307//! Ok(client) => println!("Connected"),
308//! Err(IgtlError::IoError(e)) => eprintln!("Network error: {}", e),
309//! Err(e) => eprintln!("Other error: {}", e),
310//! }
311//! ```
312
313pub mod compression;
314pub mod error;
315pub mod io;
316pub mod protocol;
317
318// Re-export commonly used types
319pub use error::{IgtlError, Result};
320
321#[cfg(test)]
322mod tests {
323 #[test]
324 fn test_module_structure() {
325 // Basic smoke test to ensure modules are accessible
326 }
327}