runsync-transfer 2026.1.0

High-throughput P2P file transfer engine: adaptive compression, end-to-end AEAD, parallel chunked pipeline over QUIC or any async transport.
Documentation
use std::io;

/// Errors produced by the transfer engine.
#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("io: {0}")]
    Io(#[from] io::Error),

    #[error("transport: {0}")]
    Transport(String),

    /// Peer closed the connection or a stream before the message was complete.
    #[error("peer closed the connection: {0}")]
    Closed(String),

    #[error("protocol violation: {0}")]
    Protocol(String),

    /// Version negotiation failed: the peer speaks a wire version we cannot serve.
    #[error("unsupported wire version {peer} (we support {ours})")]
    Version { peer: u16, ours: u16 },

    #[error("handshake failed: {0}")]
    Handshake(String),

    /// AEAD tag mismatch, truncated ciphertext, or a nonce we refuse to reuse.
    #[error("decryption failed for file {file_id} chunk {chunk}")]
    Decrypt { file_id: u32, chunk: u64 },

    #[error("compression: {0}")]
    Compress(String),

    /// Content hash of a received file did not match what the sender advertised.
    #[error("integrity check failed for {path}: expected {expected}, got {actual}")]
    Integrity {
        path: String,
        expected: String,
        actual: String,
    },

    /// A frame declared a length outside the configured limits. Guards against a
    /// hostile peer driving us into an unbounded allocation.
    #[error("frame too large: {got} bytes exceeds limit {limit}")]
    FrameTooLarge { got: usize, limit: usize },

    #[error("configuration: {0}")]
    Config(String),

    #[error("path {0:?} escapes the destination root")]
    UnsafePath(std::path::PathBuf),

    #[error("transfer cancelled")]
    Cancelled,

    #[error("worker panicked: {0}")]
    Worker(String),
}

impl Error {
    // Only the bundled transports construct this; a build with every transport
    // feature off still wants the variant available to downstream adapters.
    #[allow(dead_code)]
    pub(crate) fn transport(e: impl std::fmt::Display) -> Self {
        Error::Transport(e.to_string())
    }
    pub(crate) fn protocol(e: impl Into<String>) -> Self {
        Error::Protocol(e.into())
    }
}

pub type Result<T> = std::result::Result<T, Error>;