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}