use crate::config::OpenOptions;
use crate::error::{Error, Result};
use std::borrow::Cow;
use std::io::IoSlice;
use std::time::Duration;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct OpenRequest {
options: OpenOptions,
timeout: Option<Duration>,
}
impl OpenRequest {
#[inline]
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[inline]
#[must_use]
pub fn options(mut self, options: OpenOptions) -> Self {
self.options = options;
self
}
#[inline]
#[must_use]
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
#[inline]
pub fn open_options(&self) -> &OpenOptions {
&self.options
}
#[inline]
pub fn timeout_duration(&self) -> Option<Duration> {
self.timeout
}
#[inline]
pub fn into_parts(self) -> (OpenOptions, Option<Duration>) {
(self.options, self.timeout)
}
}
impl From<OpenOptions> for OpenRequest {
#[inline]
fn from(options: OpenOptions) -> Self {
Self::new().options(options)
}
}
#[derive(Debug, Clone)]
pub enum WritePayload<'a> {
Bytes(Cow<'a, [u8]>),
Vectored(&'a [IoSlice<'a>]),
}
impl<'a> WritePayload<'a> {
#[inline]
#[must_use]
pub fn bytes(data: &'a [u8]) -> Self {
Self::Bytes(Cow::Borrowed(data))
}
#[inline]
#[must_use]
pub fn vectored(parts: &'a [IoSlice<'a>]) -> Self {
Self::Vectored(parts)
}
#[inline]
pub fn checked_len(&self) -> Result<usize> {
match self {
Self::Bytes(data) => Ok(data.len()),
Self::Vectored(parts) => parts.iter().try_fold(0usize, |total, part| {
total
.checked_add(part.len())
.ok_or_else(|| Error::local("zmux: vectored write length overflow"))
}),
}
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
match self {
Self::Bytes(data) => data.is_empty(),
Self::Vectored(parts) => parts.iter().all(|part| part.is_empty()),
}
}
}
impl<'a> From<&'a [u8]> for WritePayload<'a> {
#[inline]
fn from(data: &'a [u8]) -> Self {
Self::bytes(data)
}
}
impl<'a> From<&'a Vec<u8>> for WritePayload<'a> {
#[inline]
fn from(data: &'a Vec<u8>) -> Self {
Self::bytes(data.as_slice())
}
}
impl<'a> From<&'a mut Vec<u8>> for WritePayload<'a> {
#[inline]
fn from(data: &'a mut Vec<u8>) -> Self {
Self::bytes(data.as_slice())
}
}
impl<'a> From<Vec<u8>> for WritePayload<'a> {
#[inline]
fn from(data: Vec<u8>) -> Self {
Self::Bytes(Cow::Owned(data))
}
}
impl<'a> From<Cow<'a, [u8]>> for WritePayload<'a> {
#[inline]
fn from(data: Cow<'a, [u8]>) -> Self {
Self::Bytes(data)
}
}
impl<'a, const N: usize> From<&'a [u8; N]> for WritePayload<'a> {
#[inline]
fn from(data: &'a [u8; N]) -> Self {
Self::bytes(data.as_slice())
}
}
impl<'a, const N: usize> From<[u8; N]> for WritePayload<'a> {
#[inline]
fn from(data: [u8; N]) -> Self {
Self::Bytes(Cow::Owned(Vec::from(data)))
}
}
impl<'a> From<&'a [IoSlice<'a>]> for WritePayload<'a> {
#[inline]
fn from(parts: &'a [IoSlice<'a>]) -> Self {
Self::vectored(parts)
}
}
#[derive(Debug, Clone)]
pub struct OpenSend<'a> {
options: OpenOptions,
payload: WritePayload<'a>,
timeout: Option<Duration>,
}
impl<'a> OpenSend<'a> {
#[inline]
#[must_use]
pub fn new(payload: impl Into<WritePayload<'a>>) -> Self {
Self {
options: OpenOptions::default(),
payload: payload.into(),
timeout: None,
}
}
#[inline]
#[must_use]
pub fn vectored(parts: &'a [IoSlice<'a>]) -> Self {
Self::new(WritePayload::vectored(parts))
}
#[inline]
#[must_use]
pub fn options(mut self, options: OpenOptions) -> Self {
self.options = options;
self
}
#[inline]
#[must_use]
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
#[inline]
pub fn open_options(&self) -> &OpenOptions {
&self.options
}
#[inline]
pub fn payload(&self) -> &WritePayload<'a> {
&self.payload
}
#[inline]
pub fn timeout_duration(&self) -> Option<Duration> {
self.timeout
}
#[inline]
pub fn into_parts(self) -> (OpenOptions, WritePayload<'a>, Option<Duration>) {
(self.options, self.payload, self.timeout)
}
}
impl<'a> From<&'a [u8]> for OpenSend<'a> {
#[inline]
fn from(data: &'a [u8]) -> Self {
Self::new(data)
}
}
impl<'a> From<&'a Vec<u8>> for OpenSend<'a> {
#[inline]
fn from(data: &'a Vec<u8>) -> Self {
Self::new(data.as_slice())
}
}
impl<'a> From<&'a mut Vec<u8>> for OpenSend<'a> {
#[inline]
fn from(data: &'a mut Vec<u8>) -> Self {
Self::new(data.as_slice())
}
}
impl<'a> From<Vec<u8>> for OpenSend<'a> {
#[inline]
fn from(data: Vec<u8>) -> Self {
Self::new(data)
}
}
impl<'a> From<Cow<'a, [u8]>> for OpenSend<'a> {
#[inline]
fn from(data: Cow<'a, [u8]>) -> Self {
Self::new(data)
}
}
impl<'a, const N: usize> From<&'a [u8; N]> for OpenSend<'a> {
#[inline]
fn from(data: &'a [u8; N]) -> Self {
Self::new(data.as_slice())
}
}
impl<'a, const N: usize> From<[u8; N]> for OpenSend<'a> {
#[inline]
fn from(data: [u8; N]) -> Self {
Self::new(data)
}
}
impl<'a> From<&'a [IoSlice<'a>]> for OpenSend<'a> {
#[inline]
fn from(parts: &'a [IoSlice<'a>]) -> Self {
Self::vectored(parts)
}
}
impl<'a> From<WritePayload<'a>> for OpenSend<'a> {
#[inline]
fn from(payload: WritePayload<'a>) -> Self {
Self::new(payload)
}
}