use std::{
cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
hash::{Hash, Hasher},
};
use crate::{dialer::Dialer, listener::Listener};
#[derive(Clone, Copy, Debug)]
pub struct Pipe
{
handle: nng_sys::nng_pipe,
}
impl Pipe
{
pub fn dialer(self) -> Option<Dialer>
{
let (dialer, id) = unsafe {
let dialer = nng_sys::nng_pipe_dialer(self.handle);
let id = nng_sys::nng_dialer_id(dialer);
(dialer, id)
};
if id > 0 { Some(Dialer::from_nng_sys(dialer)) } else { None }
}
pub fn listener(self) -> Option<Listener>
{
let (listener, id) = unsafe {
let listener = nng_sys::nng_pipe_listener(self.handle);
let id = nng_sys::nng_listener_id(listener);
(listener, id)
};
if id > 0 { Some(Listener::from_nng_sys(listener)) } else { None }
}
#[allow(clippy::missing_panics_doc)]
pub fn close(self)
{
let rv = unsafe { nng_sys::nng_pipe_close(self.handle) };
assert!(
rv == 0 || rv == nng_sys::NNG_ECLOSED as i32,
"Unexpected error code while closing pipe ({})",
rv
);
}
pub(crate) const fn handle(self) -> nng_sys::nng_pipe { self.handle }
pub(crate) fn from_nng_sys(handle: nng_sys::nng_pipe) -> Self
{
assert!(unsafe { nng_sys::nng_pipe_id(handle) > 0 }, "Pipe handle is not initialized");
Pipe { handle }
}
}
#[cfg(feature = "ffi-module")]
impl Pipe
{
pub fn nng_pipe(self) -> nng_sys::nng_pipe { self.handle() }
}
impl PartialEq for Pipe
{
fn eq(&self, other: &Pipe) -> bool
{
unsafe { nng_sys::nng_pipe_id(self.handle) == nng_sys::nng_pipe_id(other.handle) }
}
}
impl Eq for Pipe {}
impl PartialOrd for Pipe
{
fn partial_cmp(&self, other: &Pipe) -> Option<Ordering> { Some(self.cmp(other)) }
}
impl Ord for Pipe
{
fn cmp(&self, other: &Pipe) -> Ordering
{
unsafe {
let us = nng_sys::nng_pipe_id(self.handle);
let them = nng_sys::nng_pipe_id(other.handle);
us.cmp(&them)
}
}
}
impl Hash for Pipe
{
fn hash<H: Hasher>(&self, state: &mut H)
{
let id = unsafe { nng_sys::nng_pipe_id(self.handle) };
id.hash(state);
}
}
#[rustfmt::skip]
expose_options!{
Pipe :: handle -> nng_sys::nng_pipe;
GETOPT_BOOL = nng_sys::nng_pipe_get_bool;
GETOPT_INT = nng_sys::nng_pipe_get_int;
GETOPT_MS = nng_sys::nng_pipe_get_ms;
GETOPT_SIZE = nng_sys::nng_pipe_get_size;
GETOPT_SOCKADDR = nng_sys::nng_pipe_get_addr;
GETOPT_STRING = nng_sys::nng_pipe_get_string;
GETOPT_UINT64 = nng_sys::nng_pipe_get_uint64;
SETOPT = crate::util::fake_genopt;
SETOPT_BOOL = crate::util::fake_opt;
SETOPT_INT = crate::util::fake_opt;
SETOPT_MS = crate::util::fake_opt;
SETOPT_PTR = crate::util::fake_opt;
SETOPT_SIZE = crate::util::fake_opt;
SETOPT_STRING =crate::util::fake_opt;
Gets -> [LocalAddr, RemAddr, RecvMaxSize,
transport::ipc::PeerPid,
transport::tcp::NoDelay,
transport::tcp::KeepAlive,
transport::tls::Verified,
transport::websocket::RequestHeaders,
transport::websocket::ResponseHeaders];
Sets -> [];
}
#[cfg(unix)]
mod unix_impls
{
use super::*;
use crate::options::{transport::ipc, SetOpt};
impl SetOpt<ipc::PeerUid> for Pipe {}
impl SetOpt<ipc::PeerGid> for Pipe {}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum PipeEvent
{
AddPre,
AddPost,
RemovePost,
#[doc(hidden)]
Unknown(u32),
}
impl PipeEvent
{
pub(crate) fn from_code(event: u32) -> Self
{
match event {
nng_sys::NNG_PIPE_EV_ADD_PRE => PipeEvent::AddPre,
nng_sys::NNG_PIPE_EV_ADD_POST => PipeEvent::AddPost,
nng_sys::NNG_PIPE_EV_REM_POST => PipeEvent::RemovePost,
_ => PipeEvent::Unknown(event),
}
}
}