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