# Async I/O Support in TACO

The TACO format library supports optional async I/O operations through the `async` feature flag. This enables non-blocking file operations for better performance in async applications.

## Enabling Async Support

Add the `async` feature to your `Cargo.toml`:

```toml
[dependencies]
taco_format = { version = "0.1", features = ["async"] }
tokio = { version = "1.0", features = ["rt", "macros"] }
```

## Async API

When the `async` feature is enabled, the following additional types become available:

- `AsyncWriter` - Async version of the TACO writer
- `AsyncReader` - Async version of the TACO reader

## Usage Example

```rust
use taco_format::{AsyncWriter, AsyncReader, Frame, FrameData, CompressionSettings, SimulationMetadata, AtomMetadata};
use ndarray::Array2;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create async writer
    let mut writer = AsyncWriter::create(
        "trajectory.taco",
        100, // number of atoms
        0.001, // time step in ps
        SimulationMetadata::default(),
        AtomMetadata::new(),
        CompressionSettings::default(),
    ).await?;
    
    // Write frames asynchronously
    for i in 0..1000 {
        let positions = Array2::zeros((100, 3)); // 100 atoms, 3D positions
        let frame_data = FrameData::new(positions);
        let frame = Frame::new(i, i as f64 * 0.001, frame_data);
        
        writer.write_frame(frame).await?;
    }
    
    writer.finish().await?;
    
    // Read back asynchronously
    let mut reader = AsyncReader::open("trajectory.taco").await?;
    
    for i in 0..reader.num_frames() {
        let frame = reader.read_frame(i).await?;
        // Process frame...
    }
    
    Ok(())
}
```

## Implementation Details

The async implementation uses `tokio::task::spawn_blocking` to run the underlying synchronous I/O operations in a thread pool, preventing blocking of the async runtime. This provides good compatibility with existing sync code while enabling async usage patterns.

### Feature Gating

All async code is properly feature-gated with `#[cfg(feature = "async")]` to ensure:
- No async dependencies when the feature is disabled
- Minimal binary size impact for sync-only usage
- Optional tokio dependency

## Performance Considerations

- The async wrappers add minimal overhead through the use of `spawn_blocking`
- For CPU-bound compression operations, the threading helps utilize multiple cores
- File I/O benefits from async patterns in I/O-heavy applications
- Memory usage is equivalent to the sync version

## Compatibility

The async API maintains full compatibility with the synchronous API:
- Same compression settings and formats
- Identical file format and metadata
- Files written with sync API can be read with async API and vice versa
