# enigma-packet
enigma-packet defines canonical, versioned packet formats for Enigma messages. It focuses on deterministic binary framing, strict validation, and clean error handling so higher layers can plug in crypto, transport, or storage policies without duplicating serialization logic. Attachments of any size are streamed through chunked transfers, so application layers can enforce their own policies without hitting artificial limits.
## Quickstart
```rust
use enigma_packet::{
encode_message,
decode_message,
validate_message,
AttachmentChunkMeta,
AttachmentKind,
AttachmentMeta,
Message,
MessageMeta,
MessageType,
};
use uuid::Uuid;
let text = Message {
id: Uuid::new_v4(),
sender: "alice".into(),
receiver: "bob".into(),
timestamp_ms: 1,
msg_type: MessageType::Text,
payload: b"hello".to_vec(),
meta: MessageMeta::Basic {
content_type: Some("text/plain".into()),
},
};
validate_message(&text)?;
let packet = encode_message(&text)?;
let decoded = decode_message(&packet)?;
assert_eq!(decoded, text);
```
Attachments are advertised once, streamed through chunk packets, and finalized explicitly. The crate encodes the transfer metadata inside the packets while leaving network/storage policy to the caller.
```rust
let attachment_id = Uuid::new_v4();
let init = Message {
msg_type: MessageType::AttachmentInit,
payload: Vec::new(),
meta: MessageMeta::AttachmentInit(AttachmentMeta {
attachment_id,
kind: AttachmentKind::File,
filename: Some("video.mp4".into()),
content_type: Some("video/mp4".into()),
total_size: 12_345_678_901,
chunk_size: 1024 * 512,
chunk_count: 24_102,
sha256: None,
created_at_ms: Some(1),
}),
..text.clone()
};
let chunk = Message {
msg_type: MessageType::AttachmentChunk,
payload: vec![0_u8; 1024 * 512],
meta: MessageMeta::AttachmentChunk(AttachmentChunkMeta {
attachment_id,
index: 0,
offset: 0,
chunk_size: 1024 * 512,
total_size: Some(12_345_678_901),
}),
..text.clone()
};
```
## Packet Format Overview
Each packet carries one `Message` encoded with fixed bincode settings and wrapped in a deterministic frame:
| MAGIC | 4 bytes | `ENP1` identifier |
| VERSION | 1 byte | currently `1` |
| FLAGS | 1 byte | reserved for future extensions |
| RESERVED | 2 bytes | big-endian zero for now |
| BODY_LEN | 4 bytes | big-endian length of the encoded body |
| BODY | variable | bincode `Message` payload |
Packets must be at least 12 bytes (header only) and at most 16 MiB. The body length is also capped at 16 MiB minus header to keep allocations safe.
## Validation Summary
Messages are validated before encoding and after decoding:
- sender and receiver must be non-empty UTF-8 strings up to 64 characters
- timestamp must be greater than zero
- text payloads must be valid UTF-8 but have no enforced length limit
- attachment init packets require metadata describing total size, chunking plan, and filenames for file transfers
- attachment chunk packets must reference the declared chunk sizing, include non-empty payloads, and obey deterministic offsets
- attachment end/abort/ack packets must provide metadata and empty payloads
See `docs/validation.md` for the full rule set and `docs/api.md` for detailed function descriptions.