use {
super::PipeModeTag,
std::mem,
windows_sys::Win32::{
Storage::FileSystem::{PIPE_ACCESS_DUPLEX, PIPE_ACCESS_INBOUND, PIPE_ACCESS_OUTBOUND},
System::Pipes::{
PIPE_READMODE_BYTE, PIPE_READMODE_MESSAGE, PIPE_TYPE_BYTE, PIPE_TYPE_MESSAGE,
},
},
};
#[repr(u32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum PipeDirection {
ClientToServer = PIPE_ACCESS_INBOUND,
ServerToClient = PIPE_ACCESS_OUTBOUND,
Duplex = PIPE_ACCESS_DUPLEX,
}
impl PipeDirection {
pub const fn client_role(self) -> PipeStreamRole {
match self {
Self::ClientToServer => PipeStreamRole::Sender,
Self::ServerToClient => PipeStreamRole::Recver,
Self::Duplex => PipeStreamRole::RecverAndSender,
}
}
pub const fn server_role(self) -> PipeStreamRole {
match self {
Self::ClientToServer => PipeStreamRole::Recver,
Self::ServerToClient => PipeStreamRole::Sender,
Self::Duplex => PipeStreamRole::RecverAndSender,
}
}
}
impl TryFrom<u32> for PipeDirection {
type Error = ();
fn try_from(op: u32) -> Result<Self, ()> {
Ok(match op {
PIPE_ACCESS_INBOUND => Self::ClientToServer,
PIPE_ACCESS_OUTBOUND => Self::ServerToClient,
PIPE_ACCESS_DUPLEX => Self::Duplex,
_ => return Err(()),
})
}
}
impl From<PipeDirection> for u32 {
fn from(op: PipeDirection) -> Self { unsafe { mem::transmute(op) } }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum PipeStreamRole {
Recver,
Sender,
RecverAndSender,
}
impl PipeStreamRole {
pub const fn direction_as_server(self) -> PipeDirection {
match self {
Self::Recver => PipeDirection::ClientToServer,
Self::Sender => PipeDirection::ServerToClient,
Self::RecverAndSender => PipeDirection::Duplex,
}
}
pub const fn direction_as_client(self) -> PipeDirection {
match self {
Self::Recver => PipeDirection::ServerToClient,
Self::Sender => PipeDirection::ClientToServer,
Self::RecverAndSender => PipeDirection::Duplex,
}
}
pub(crate) const fn get_for_rm_sm<Rm: PipeModeTag, Sm: PipeModeTag>() -> Self {
match (Rm::MODE, Sm::MODE) {
(Some(..), Some(..)) => Self::RecverAndSender,
(Some(..), None) => Self::Recver,
(None, Some(..)) => Self::Sender,
(None, None) => unimplemented!(),
}
}
}
#[repr(u32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum PipeMode {
Bytes = PIPE_TYPE_BYTE,
Messages = PIPE_TYPE_MESSAGE,
}
impl PipeMode {
#[inline]
pub const fn to_pipe_type(self) -> u32 { self as _ }
pub const fn to_readmode(self) -> u32 {
match self {
Self::Bytes => PIPE_READMODE_BYTE,
Self::Messages => PIPE_READMODE_MESSAGE,
}
}
}
impl TryFrom<u32> for PipeMode {
type Error = ();
fn try_from(op: u32) -> Result<Self, ()> {
#[allow(unreachable_patterns)] match op {
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE => Ok(Self::Bytes),
PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE => Ok(Self::Messages),
_ => Err(()),
}
}
}