smpp-codec 0.2.1

A comprehensive SMPP v5 protocol codec for Rust.
Documentation
# Performance Guide


The `smpp-codec` library is designed to be flexible and efficient, decoupling **what** is encoded from **how** it is written. This gives you strict control over allocation and system calls.

## Encoding & Buffering


All PDU structures implement an `encode` method that accepts any type implementing `std::io::Write`.

```rust
pub fn encode(&self, writer: &mut impl Write) -> Result<(), PduError>
```

Your choice of `writer` dramatically impacts performance.

### 1. In-Memory Buffer (Recommended for most cases)

Writing to a `Vec<u8>` is extremely fast because it involves only memory operations (no system calls).

```rust
let mut buffer = Vec::with_capacity(512); // Pre-allocate to avoid re-sizing
pdu.encode(&mut buffer)?; // Fast memory copy
stream.write_all(&buffer)?; // ONE system call to send entire PDU
```

### 2. Buffered Writer (`BufWriter`)

If you prefer not to manage a `Vec` manually, wrap your stream in a `BufWriter`. This handles the buffering for you.

```rust
use std::io::BufWriter;

let mut writer = BufWriter::new(tcp_stream);
pdu.encode(&mut writer)?; // Writes to internal buffer (fast)
writer.flush()?;          // Flushes buffer to network (ONE system call)
```

### 3. Raw Stream (⚠️ Performance Warning)

**Avoiding this pattern is critical for high-throughput applications.**

If you pass a raw `TcpStream` (or File) directly to `encode`, the library will make a separate system call for every field it writes.

```rust
// ❌ INEFFICIENT
pdu.encode(&mut tcp_stream)?; 
```

**Why is this slow?**
`SubmitSmRequest` has ~20 fields. A raw encode results in ~20 tiny system calls. Context switching for each call kills throughput.

## Memory Reusage


For maximum performance in a loop, reuse your `Vec<u8>` to avoid repeated heap allocations.

```rust
let mut buffer = Vec::with_capacity(2048);

for pdu in pdus {
    buffer.clear(); // Resets length but keeps capacity
    pdu.encode(&mut buffer)?;
    stream.write_all(&buffer)?;
}
```