NntpResponse

Struct NntpResponse 

Source
pub struct NntpResponse {
    pub status_code: u16,
    pub is_multiline: bool,
    pub data: Vec<u8>,
}
Expand description

Represents a parsed NNTP response

Fields§

§status_code: u16

Status code (e.g., 200, 381, 500)

§is_multiline: bool

Whether this is a multiline response

§data: Vec<u8>

Complete response data including status line

Implementations§

Source§

impl NntpResponse

Source

pub fn parse_status_code(data: &[u8]) -> Option<u16>

Parse a status code from response data

Per RFC 3977 §3.2, responses begin with a 3-digit status code (ASCII digits ‘0’-‘9’).

Optimization: Direct byte-to-digit conversion without UTF-8 validation. Status codes are guaranteed to be ASCII digits per the RFC.

Source

pub fn is_multiline_response(status_code: u16) -> bool

Check if a response indicates a multiline response

Per RFC 3977 §3.4.1, certain status codes indicate multiline data follows.

§Multiline Response Codes
  • 1xx: All informational responses (100-199)
  • 2xx: Specific codes - 215, 220, 221, 222, 224, 225, 230, 231, 282
Source

pub fn has_terminator_at_end(data: &[u8]) -> bool

Check if data ends with the NNTP multiline terminator

Per RFC 3977 §3.4.1:

Multiline blocks are terminated by a line containing only a period:
CRLF "." CRLF
Which appears in the data stream as: \r\n.\r\n

Optimization: Single suffix check, no scanning.

Source

pub fn find_terminator_end(data: &[u8]) -> Option<usize>

Find the position of the NNTP multiline terminator in data

Returns the position AFTER the terminator (exclusive end), or None if not found. This handles the case where extra data appears after the terminator in the same chunk.

Per RFC 3977 §3.4.1, the terminator is exactly “\r\n.\r\n” (CRLF, dot, CRLF).

Optimization: Uses memchr::memchr_iter() to find ‘\r’ bytes (SIMD-accelerated), then validates the full 5-byte pattern. This eliminates the need to create new slices on each iteration (which the manual loop approach requires with &data[pos..]).

Benchmarks show this is 72% faster for small responses (37ns → 13ns) and 64% faster for medium responses (109ns → 40ns) compared to the manual loop that creates a new slice on each iteration.

Source

pub fn has_spanning_terminator( tail: &[u8], tail_len: usize, current: &[u8], current_len: usize, ) -> bool

Check if a terminator spans across a boundary between tail and current chunk

This handles the case where a multiline terminator is split across two read chunks. For example: previous chunk ends with “\r\n.” and current starts with “\r\n”

Per RFC 3977 §3.4.1, the terminator is exactly “\r\n.\r\n” (CRLF, dot, CRLF).

Source

pub fn is_disconnect(data: &[u8]) -> bool

Check if response is a disconnect/goodbye (205)

Per RFC 3977 §5.4, code 205 indicates “Connection closing” / “Goodbye”.

Optimization: Direct byte prefix check, no parsing.

Source

pub fn extract_message_id(command: &str) -> Option<MessageId<'_>>

Extract message-ID from command arguments using fast byte searching

Per RFC 5536 §3.1.3, message-IDs have the format <local-part@domain>.

Examples:

  • <article123@news.example.com>
  • <20231014.123456@server.domain>

Optimization: Uses memchr for fast ‘<’ and ‘>’ detection.

Source

pub fn validate_message_id(msgid: &str) -> bool

Validate message-ID format according to RFC 5536 §3.1.3

A valid message-ID must:

  • Start with ‘<’ and end with ‘>’
  • Contain exactly one ‘@’ character
  • Have content before and after the ‘@’ (local-part and domain)

Per RFC 5536 §3.1.3:

msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]

Note: This is a basic validation - full RFC 5536 validation is more complex.

Source

pub fn has_multiline_terminator(data: &[u8]) -> bool

Check if data contains the end-of-multiline marker (legacy method)

Trait Implementations§

Source§

impl Clone for NntpResponse

Source§

fn clone(&self) -> NntpResponse

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NntpResponse

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for NntpResponse

Source§

fn eq(&self, other: &NntpResponse) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for NntpResponse

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more