openigtlink_rust/
lib.rs

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