Skip to main content

WriteBuf

Struct WriteBuf 

Source
pub struct WriteBuf { /* private fields */ }
Expand description

Flat byte slab for outbound protocol frames.

sk_buff headroom model: payload is appended at the tail, protocol headers are prepended into reserved headroom. The result is one contiguous data() slice for the write syscall.

Fixed capacity. No growth.

§Layout

[ headroom          | payload data         | tailroom    ]
^                   ^                      ^             ^
0                   head                   tail          buf.len()

After clear(): head = headroom, tail = headroom.

§Modes

One-shot message (sk_buff style): prepend() / append() to build a single frame, data() to send, clear() between frames. This is what most protocol-frame builders want.

Cursor FIFO: spare() / filled() to stage bytes (e.g. from a sans-IO codec writing into the tail region), data() to send, advance(n) after partial writes. Auto-reset on full drain means the buffer is reusable across cycles without an explicit clear(). This is what TLS adapters use for ciphertext staging.

§Examples

use nexus_net::buf::WriteBuf;

let mut wbuf = WriteBuf::new(128, 14);

// Build message: payload first, then header
wbuf.append(b"Hello, world!");
wbuf.prepend(&[0x81, 0x0D]); // WS text frame header

// data() = contiguous [header | payload]
assert_eq!(&wbuf.data()[..2], &[0x81, 0x0D]);
assert_eq!(&wbuf.data()[2..], b"Hello, world!");

// For partial writes:
// let n = socket.write(wbuf.data())?;
// wbuf.advance(n);

Implementations§

Source§

impl WriteBuf

Source

pub fn new(capacity: usize, headroom: usize) -> WriteBuf

Create with total capacity and reserved headroom.

Usable tailroom = capacity - headroom.

§Panics

Panics if headroom >= capacity.

Source

pub fn prepend(&mut self, src: &[u8])

Prepend bytes into headroom (protocol headers). Moves head backward.

§Panics

Panics if src.len() > self.headroom().

Source

pub fn append(&mut self, src: &[u8])

Append bytes at tail (payload data).

§Panics

Panics if src.len() > self.tailroom().

Source

pub fn extend_zeroed(&mut self, n: usize)

Extend the buffer with n zeroed bytes at the tail. No heap allocation — zeroes directly in the existing buffer.

§Panics

Panics if n > self.tailroom().

Source

pub fn data(&self) -> &[u8]

Complete outbound data (contiguous: headers + payload).

Source

pub fn data_mut(&mut self) -> &mut [u8]

Mutable access to outbound data. For in-place operations like XOR masking.

Source

pub fn spare(&mut self) -> &mut [u8]

Writable tail region for direct in-place writes.

Pair with filled() to commit bytes after a successful write. Used by sans-IO codecs that produce bytes directly (e.g. TlsCodec::write_tls_to(&mut buf.spare())).

Returns buf[tail .. buf.len()]. May be empty if tail has reached the buffer boundary.

Source

pub fn filled(&mut self, n: usize)

Commit n bytes written into spare().

§Panics

Panics if n would push tail past the buffer boundary.

Source

pub fn advance(&mut self, n: usize)

Consume n bytes from front after a partial write.

If the buffer becomes empty after advance, resets head and tail to reset_offset (free — no memmove, just cursor reset). This makes WriteBuf usable as a cursor FIFO: encrypt → drain partial → encrypt more → drain more, with auto-reclaim when fully drained. Calling clear() after a fully-drained advance() is now redundant.

§Panics

Panics if n > self.len().

Source

pub fn headroom(&self) -> usize

Bytes available for prepend.

Source

pub fn tailroom(&self) -> usize

Bytes available for append.

Source

pub fn len(&self) -> usize

Bytes of outbound data.

Source

pub fn is_empty(&self) -> bool

Whether the buffer has no outbound data.

Source

pub fn shrink_tail(&mut self, n: usize)

Remove n bytes from the end. For Content-Length backfill after shifting body bytes left.

§Panics

Panics if n > self.len().

Source

pub fn clear(&mut self)

Reset for next message. Cursors return to headroom offset.

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Same for T

Source§

type Output = T

Should always be Self
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V