socker 1.0.0

Sans-IO SOCKS4, SOCKS4a, SOCKS5 and SOCKS5h protocol implementation
Documentation
//! Helpers shared by the unit-test modules of the protocol implementations.
#![expect(
    clippy::indexing_slicing,
    reason = "test indices are checked against the encoded lengths above"
)]
#![expect(
    clippy::arithmetic_side_effects,
    reason = "test arithmetic on small encodings cannot overflow"
)]

use crate::{
    DecodeStatus,
    Message,
};

/// Encodes `message`, then checks that every strict prefix of the encoding
/// decodes as [`DecodeStatus::Partial`] and that the full encoding decodes
/// back into an equal message consuming exactly its own bytes.
///
/// # Panics
///
/// Panics if any stage of encoding or decoding does not behave exactly as
/// described above.
pub fn round_trip<T>(message: &T)
where
    T: Message + PartialEq + std::fmt::Debug,
{
    let mut buffer = Vec::new();
    message
        .encode(&mut buffer)
        .expect("encoding a well-formed message must succeed");
    assert_eq!(
        buffer.len(),
        message.encoded_len(),
        "encoded_len must match the actual encoding"
    );

    for prefix_length in 0 .. buffer.len() - 1 {
        match T::decode(&buffer[.. prefix_length]) {
            | Ok(DecodeStatus::Partial) => {},
            | other => {
                panic!(
                    "decoding a strict prefix of length {prefix_length} must be Partial, got \
                     {other:?}"
                )
            },
        }
    }

    match T::decode(&buffer) {
        | Ok(DecodeStatus::Complete((decoded, consumed))) => {
            assert_eq!(
                consumed,
                buffer.len(),
                "decoding must consume exactly the encoded message"
            );
            assert_eq!(&decoded, message, "round-trip must preserve the message");
        },
        | other => panic!("decoding a complete message must succeed, got {other:?}"),
    }
}

/// Returns the wire encoding of `message`.
///
/// # Panics
///
/// Panics if encoding fails.
pub fn encoded<T: Message>(message: &T) -> Vec<u8> {
    let mut buffer = Vec::new();
    message
        .encode(&mut buffer)
        .expect("encoding a well-formed message must succeed");
    buffer
}