dope-uring 0.39.0

Owned io_uring backend for dope
Documentation
use std::{mem, num};

use dope_sys::{
    io::reactor::complete::{self, flags},
    memory::buffer,
};
use flags::Flow;
use o3::base::num::bounded;

const BUFFER: u32 = 1 << 0;
const MORE: u32 = 1 << 1;
const SOCK_NONEMPTY: u32 = 1 << 2;
const SHIFT: u32 = 16;
const INDEX: u32 = (u16::MAX as u32) << SHIFT;
const KNOWN: u32 = BUFFER | MORE | SOCK_NONEMPTY | INDEX;

#[derive(Clone, Copy, Eq, PartialEq, Debug)]
#[repr(transparent)]
pub struct Flags(u32);

#[derive(Clone, Copy, Eq, PartialEq, Debug)]
#[repr(transparent)]
pub struct Buffer(u16);

#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Meta {
    buffer: Option<Buffer>,
    flow: Flow,
    socket_nonempty: bool,
}

#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct Invalid {
    flags: Flags,
}

impl Flags {
    pub(crate) const fn new(raw: u32) -> Self {
        Self(raw)
    }
}

impl complete::Flags for Flags {
    type Meta = Meta;
    type Invalid = Invalid;

    fn meta(self) -> Meta {
        let raw = self.0;
        let buffer = if raw & BUFFER == 0 {
            None
        } else {
            Some(Buffer((raw >> SHIFT) as u16))
        };
        Meta {
            buffer,
            flow: if raw & MORE == 0 {
                Flow::Last
            } else {
                Flow::More
            },
            socket_nonempty: raw & SOCK_NONEMPTY != 0,
        }
    }

    fn decode(self) -> Result<Meta, Invalid> {
        if !self.is_valid() {
            return Err(Invalid { flags: self });
        }
        Ok(self.meta())
    }

    fn is_valid(self) -> bool {
        let raw = self.0;
        raw & !KNOWN == 0 && (raw & BUFFER != 0 || raw & INDEX == 0)
    }
}

impl buffer::Index for Buffer {
    const ZERO: Self = Self(0);

    fn advance(&mut self) {
        self.0 = self.0.wrapping_add(1);
    }

    fn offset(self, stride: num::NonZero<u32>) -> bounded::U64<0, { u64::MAX }> {
        bounded::U64::clamp(self.0 as u64 * stride.get() as u64)
    }

    fn is_within(self, capacity: num::NonZero<u16>) -> bool {
        self.0 < capacity.get()
    }
}

impl From<Invalid> for Flags {
    fn from(invalid: Invalid) -> Self {
        invalid.flags
    }
}

impl flags::Meta for Meta {
    type Buffer = Buffer;

    fn buffer(self) -> Option<Buffer> {
        self.buffer
    }

    fn flow(self) -> Flow {
        self.flow
    }
}

impl From<Meta> for Flags {
    fn from(meta: Meta) -> Self {
        let buffer = match meta.buffer {
            Some(buffer) => BUFFER | (u32::from(buffer.0) << SHIFT),
            None => 0,
        };
        let flow = match meta.flow {
            Flow::Last => 0,
            Flow::More => MORE,
        };
        Self(buffer | flow | (u32::from(meta.socket_nonempty) * SOCK_NONEMPTY))
    }
}

const _: () = {
    assert!(mem::size_of::<Flags>() == mem::size_of::<u32>());
    assert!(mem::size_of::<Invalid>() == mem::size_of::<Flags>());
    assert!(mem::size_of::<Buffer>() == mem::size_of::<u16>());
    assert!(mem::size_of::<Flow>() == mem::size_of::<bool>());
    assert!(mem::size_of::<Option<Buffer>>() == mem::size_of::<u32>());
    assert!(
        mem::size_of::<Meta>() == mem::size_of::<Option<Buffer>>() + 2 * mem::size_of::<bool>()
    );
    assert!(mem::align_of::<Meta>() == mem::align_of::<u16>());
};