net-bytes 0.3.0

A Rust library for handling file sizes, download speeds, and download acceleration with support for both SI and IEC standards
Documentation
# Net Bytes


[![Crates.io](https://img.shields.io/crates/v/net-bytes)](https://crates.io/crates/net-bytes)
[![Documentation](https://docs.rs/net-bytes/badge.svg)](https://docs.rs/net-bytes)
[![License](https://img.shields.io/crates/l/net-bytes)](LICENSE-MIT)

A lightweight, zero-dependency Rust library for handling file sizes, download speeds, and download acceleration with support for both SI (base-1000) and IEC (base-1024) standards.

## Features


- **Zero Dependencies**: Pure Rust implementation with no external dependencies
- **File Size Formatting**: Format file sizes with automatic unit selection (B, KB/KiB, MB/MiB, etc.)
- **Download Speed Calculation**: Calculate and format download speeds with nanosecond precision
- **Download Acceleration**: Measure and format download acceleration with ETA prediction
- **Dual Standard Support**: Both SI (base-1000) and IEC (base-1024) standards
- **Fixed-Point Precision**: Uses integer arithmetic with 6 decimal places of precision, avoiding floating-point errors
- **High Performance**: Efficient implementation using `u128`/`i128` for overflow-safe calculations

## Installation


Add this to your `Cargo.toml`:

```toml
[dependencies]
net-bytes = "0.3"
```

## Usage


### File Sizes


```rust
use net_bytes::{FileSize, NonZeroFileSize};
use std::num::NonZeroU64;

// Create a file size of 1.5 MB (SI standard)
let size = FileSize::new(1_500_000);
println!("Size: {}", size.to_si_string()); // Output: 1.50 MB

// Using IEC standard (base-1024)
println!("Size (IEC): {}", size.to_iec_string()); // Output: 1.43 MiB

// Non-zero file size
let non_zero = NonZeroFileSize::new(NonZeroU64::new(1_500_000).unwrap());
println!("Non-zero size: {}", non_zero.to_si_string());
```

### Download Speeds


```rust
use net_bytes::DownloadSpeed;
use std::time::Duration;

// Create from bytes and duration
let speed = DownloadSpeed::new(10_000_000, Duration::from_secs(2));
println!("Speed: {}", speed.to_si_string()); // Output: 5.00 MB/s

// Or from raw bytes per second
let speed = DownloadSpeed::from_raw(5_000_000);
println!("Speed: {}", speed.to_iec_string()); // Output: 4.77 MiB/s

// Get the value in different formats
println!("Bytes/s: {}", speed.as_u64());  // Integer value
println!("Bytes/s: {}", speed.as_f64());  // Floating-point value
```

### Download Acceleration


```rust
use net_bytes::DownloadAcceleration;
use std::time::Duration;

// Create from speed change and duration
let accel = DownloadAcceleration::new(
    1_000_000,              // 1 MB/s initial speed
    5_000_000,              // 5 MB/s final speed
    Duration::from_secs(4), // over 4 seconds
);
println!("Acceleration: {}", accel.to_si_string()); // Output: 1.00 MB/s²

// Predict ETA with acceleration
let current_speed = 2_000_000; // 2 MB/s
let remaining_bytes = 10_000_000; // 10 MB
if let Some(eta) = accel.predict_eta(current_speed, remaining_bytes) {
    println!("ETA: {:.1} seconds", eta);
}
```

## API Reference


### FileSize


| Method | Description |
|--------|-------------|
| `new(bytes: u64) -> Self` | Create a new file size |
| `as_u64() -> u64` | Get the size in bytes |
| `to_si_string() -> String` | Format using SI units (KB, MB, GB, etc.) |
| `to_iec_string() -> String` | Format using IEC units (KiB, MiB, GiB, etc.) |
| `get_si_parts() -> (String, &'static str)` | Get (value, unit) pair in SI standard |
| `get_iec_parts() -> (String, &'static str)` | Get (value, unit) pair in IEC standard |
| `to_nonzero() -> Option<NonZeroFileSize>` | Convert to NonZeroFileSize if not zero |

### NonZeroFileSize


| Method | Description |
|--------|-------------|
| `new(bytes: NonZeroU64) -> Self` | Create a new non-zero file size |
| `as_u64() -> u64` | Get the size in bytes |
| `get_nonzero() -> NonZeroU64` | Get the size as NonZeroU64 |
| `to_si_string() -> String` | Format using SI units |
| `to_iec_string() -> String` | Format using IEC units |

### DownloadSpeed


| Method | Description |
|--------|-------------|
| `new(bytes: u64, duration: Duration) -> Self` | Create from bytes and duration |
| `from_raw(bytes_per_second: u64) -> Self` | Create from bytes per second |
| `as_u64() -> u64` | Get speed as u64 (floored) |
| `as_f64() -> f64` | Get speed as f64 |
| `as_scaled() -> u128` | Get internal scaled value |
| `to_si_string() -> String` | Format using SI units (KB/s, MB/s, etc.) |
| `to_iec_string() -> String` | Format using IEC units (KiB/s, MiB/s, etc.) |

### DownloadAcceleration


| Method | Description |
|--------|-------------|
| `new(initial_speed: u64, final_speed: u64, duration: Duration) -> Self` | Create from speed change and duration |
| `from_raw(bytes_per_second_sq: i64) -> Self` | Create from bytes per second squared |
| `as_i64() -> i64` | Get acceleration as i64 (floored) |
| `as_f64() -> f64` | Get acceleration as f64 |
| `as_scaled() -> i128` | Get internal scaled value |
| `predict_eta(current_speed: u64, remaining_bytes: u64) -> Option<f64>` | Predict ETA in seconds |
| `to_si_string() -> String` | Format using SI units (KB/s², MB/s², etc.) |
| `to_iec_string() -> String` | Format using IEC units (KiB/s², MiB/s², etc.) |

## License


Licensed under either of:

- [MIT License]LICENSE-MIT
- [Apache License, Version 2.0]LICENSE-APACHE

at your option.