noxtls-io 0.2.10

Internal implementation crate for noxtls: transport traits and blocking/async TLS record I/O adapters.
Documentation
// Copyright (c) 2019-2026, Argenox Technologies LLC
// All rights reserved.
//
// SPDX-License-Identifier: GPL-2.0-only OR LicenseRef-Argenox-Commercial-License
//
// This file is part of the NoxTLS Library.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by the
// Free Software Foundation; version 2 of the License.
//
// Alternatively, this file may be used under the terms of a commercial
// license from Argenox Technologies LLC.
//
// See `noxtls/LICENSE` and `noxtls/LICENSE.md` in this repository for full details.
// CONTACT: info@argenox.com

//! Async helpers that combine [`super::stream_async::AsyncByteStream`] with TLS record deframing.

use crate::internal_alloc::Vec;
use crate::record::TlsRecordDeframer;

use super::stream_async::AsyncByteStream;
use super::TransportError;

/// Reads from `stream` until `deframer` yields one complete TLS record packet.
///
/// # Errors
///
/// Returns [`TransportError::UnexpectedEof`] when the stream closes before a full record arrives,
/// or transport errors from the underlying async read.
pub async fn noxtls_read_record_async<S: AsyncByteStream>(
    stream: &mut S,
    deframer: &mut TlsRecordDeframer,
) -> Result<Vec<u8>, TransportError> {
    loop {
        if let Some(packet) = deframer
            .pop_packet()
            .map_err(|_| TransportError::IoFailed("tls record deframer rejected length"))?
        {
            return Ok(packet);
        }
        let mut chunk = [0_u8; 4096];
        let n = stream.read_async(&mut chunk).await?;
        if n == 0 {
            return Err(TransportError::UnexpectedEof);
        }
        deframer.push(&chunk[..n]);
    }
}

/// Writes every byte in `data` through `stream` (symmetry with blocking `write_all`).
pub async fn noxtls_write_all_async<S: AsyncByteStream>(
    stream: &mut S,
    data: &[u8],
) -> Result<(), TransportError> {
    stream.write_all_async(data).await
}