nomad_protocol/lib.rs
1//! # NOMAD Protocol
2//!
3//! **N**etwork-**O**ptimized **M**obile **A**pplication **D**atagram
4//!
5//! NOMAD is a secure, UDP-based state synchronization protocol designed for
6//! real-time applications over unreliable networks. It provides:
7//!
8//! - **Security**: End-to-end authenticated encryption with forward secrecy
9//! - **Mobility**: Seamless operation across IP address changes (roaming)
10//! - **Latency**: Sub-100ms reconnection, optional client-side prediction
11//! - **Simplicity**: Fixed cryptographic suite, no negotiation
12//! - **Generality**: State-agnostic synchronization framework
13//!
14//! ## Feature Flags
15//!
16//! - `transport` (default): Transport layer (frames, RTT, pacing, sockets)
17//! - `crypto` (default): Security layer (Noise_IK, XChaCha20-Poly1305)
18//!
19//! ## Modules
20//!
21//! - [`core`]: Core traits, constants, and error types (always included)
22//! - [`transport`]: Transport layer (requires `transport` feature)
23//! - [`crypto`]: Security layer (requires `crypto` feature)
24//!
25//! ## Example Usage
26//!
27//! ```rust
28//! use nomad_protocol::prelude::*;
29//!
30//! // Define your state type
31//! #[derive(Clone)]
32//! struct MyState {
33//! counter: u64,
34//! }
35//!
36//! #[derive(Clone)]
37//! struct MyDiff {
38//! delta: i64,
39//! }
40//!
41//! impl SyncState for MyState {
42//! type Diff = MyDiff;
43//! const STATE_TYPE_ID: &'static str = "example.counter.v1";
44//!
45//! fn diff_from(&self, old: &Self) -> Self::Diff {
46//! MyDiff {
47//! delta: self.counter as i64 - old.counter as i64,
48//! }
49//! }
50//!
51//! fn apply_diff(&mut self, diff: &Self::Diff) -> Result<(), ApplyError> {
52//! self.counter = (self.counter as i64 + diff.delta) as u64;
53//! Ok(())
54//! }
55//!
56//! fn encode_diff(diff: &Self::Diff) -> Vec<u8> {
57//! diff.delta.to_le_bytes().to_vec()
58//! }
59//!
60//! fn decode_diff(data: &[u8]) -> Result<Self::Diff, DecodeError> {
61//! if data.len() < 8 {
62//! return Err(DecodeError::UnexpectedEof);
63//! }
64//! let delta = i64::from_le_bytes(data[..8].try_into().unwrap());
65//! Ok(MyDiff { delta })
66//! }
67//! }
68//! ```
69
70#![forbid(unsafe_code)]
71#![warn(missing_docs)]
72#![cfg_attr(docsrs, feature(doc_cfg))]
73
74// Core module (always included)
75pub mod core;
76
77// Transport layer (feature-gated)
78#[cfg(feature = "transport")]
79#[cfg_attr(docsrs, doc(cfg(feature = "transport")))]
80pub mod transport;
81
82// Crypto layer (feature-gated)
83#[cfg(feature = "crypto")]
84#[cfg_attr(docsrs, doc(cfg(feature = "crypto")))]
85pub mod crypto;
86
87// Sync layer (feature-gated)
88#[cfg(feature = "sync")]
89#[cfg_attr(docsrs, doc(cfg(feature = "sync")))]
90pub mod sync;
91
92// Extensions (feature-gated)
93#[cfg(feature = "extensions")]
94#[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
95pub mod extensions;
96
97// Client API (feature-gated)
98#[cfg(feature = "client")]
99#[cfg_attr(docsrs, doc(cfg(feature = "client")))]
100pub mod client;
101
102// Server API (feature-gated)
103#[cfg(feature = "server")]
104#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
105pub mod server;
106
107/// Prelude module for convenient imports.
108pub mod prelude {
109 // Core traits and types
110 pub use crate::core::*;
111
112 // Transport types (when enabled) - exclude SessionId to avoid conflict with crypto
113 #[cfg(feature = "transport")]
114 pub use crate::transport::{
115 ConnectionPhase, ConnectionState, DataFrame, DataFrameHeader, FrameFlags, FramePacer,
116 FrameType, MigrationState, NomadSocket, NomadSocketBuilder, PacerAction,
117 PayloadHeader, RetransmitController, RttEstimator, SendReason, TimestampTracker,
118 TransportError, TransportResult,
119 };
120
121 // Crypto types (when enabled) - SessionId comes from here
122 #[cfg(feature = "crypto")]
123 pub use crate::crypto::*;
124}
125
126// Re-export commonly used items at crate root
127pub use core::{ApplyError, DecodeError, NomadError, SyncState};
128
129#[cfg(feature = "transport")]
130pub use transport::{
131 ConnectionPhase, ConnectionState, DataFrame, DataFrameHeader, FrameFlags, FramePacer,
132 FrameType, NomadSocket, PayloadHeader, RttEstimator, SessionId,
133};