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}