tachyon-i2p 0.0.2

Safe async wrapper around i2pd-sys (native I2P `.b32.i2p` eepsite support).
Documentation
//! Safe async wrapper around `i2pd-sys`, giving Tokio code a [`Destination`] (an I2P eepsite
//! identity, reachable at a `.b32.i2p` address) with an [`I2pStream`] connection type that
//! implements [`AsyncRead`](tokio::io::AsyncRead)/[`AsyncWrite`](tokio::io::AsyncWrite) — no
//! external `i2pd`/Java-I2P process, no SAM bridge, no separate service to run alongside your
//! binary.
//!
//! # Crypto backend: `aws-lc` (default) vs `fips`
//!
//! Mirrors `i2pd-sys`'s own two features, passed straight through:
//!
//! - **`aws-lc`** (default): regular AWS-LC via `i2pd-sys`'s `aws-lc` feature.
//! - **`fips`**: the FIPS 140-3-validated AWS-LC-FIPS module instead, via `i2pd-sys`'s `fips`
//!   feature. **`fips` wins if both end up enabled** (e.g. a dependent crate's own default
//!   reaching for `aws-lc` while a workspace-wide `fips` flag also reaches in here) -- see
//!   `i2pd-sys`'s crate docs for why an inert, unused `aws-lc-sys` compiled in alongside it is
//!   harmless. See `i2pd-sys`'s "FIPS" README section for what `fips` does and does not get you
//!   before reaching for it to satisfy a compliance requirement.
//!
//! # Why this crate exists, and why it's `unsafe` internally
//!
//! `libi2pd` (the underlying router, from [PurpleI2P/i2pd](https://github.com/PurpleI2P/i2pd))
//! is a C++ library with no stable C ABI. `i2pd-sys` bridges it through a small hand-written
//! `extern "C"` shim; this crate is where every `unsafe` call site into that shim lives, so that
//! `tachyon-web` itself never has to relax its own `forbid(unsafe_code)`. **The public API below
//! is 100% safe Rust** — no `pub unsafe fn`, no raw pointers exposed — but that safety rests
//! entirely on this crate's own review of libi2pd's threading/ownership contracts (documented
//! inline at each `unsafe` block, and in `i2pd-sys/shim/shim.h`), not on any external memory-safety
//! guarantee the way a pure-Rust dependency would give you. See `tachyon-web`'s `i2p` feature
//! docs for the practical implication of that distinction.
//!
//! # Basic usage
//!
//! ```rust,no_run
//! # async fn example() -> Result<(), tachyon_i2p::I2pError> {
//! use tachyon_i2p::{I2pRouter, SigType};
//!
//! let router = I2pRouter::start("my-eepsite").await?;
//! let mut dest = router
//!     // Empty slice: publish libi2pd's own automatic hybrid encryption set (ElGamal +
//!     // ECIES-X25519, plus ML-KEM-768 if built against a post-quantum-capable backend) rather
//!     // than a single fixed algorithm -- see `CryptoType`'s docs to narrow that down instead.
//!     .destination_from_keys_file("my-eepsite.keys", true, SigType::default(), &[])
//!     .await?;
//! println!("reachable at http://{}", dest.b32_address());
//!
//! loop {
//!     let _stream = dest.accept().await?; // implements AsyncRead + AsyncWrite
//!     // ... spawn a task to serve it ...
//! }
//! # }
//! ```
//!
//! Only one [`I2pRouter`] may run per process — libi2pd keeps its router context as a
//! process-wide global, not a per-instance object.

#[cfg(not(any(feature = "aws-lc", feature = "fips")))]
compile_error!(
    "no crypto backend selected -- enable exactly one of the `aws-lc` (default) or `fips` \
     features."
);

mod destination;
mod error;
mod router;
mod stream;

pub use destination::Destination;
pub use error::I2pError;
pub use router::{CryptoType, I2pRouter, SigType};
pub use stream::I2pStream;