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};