use std::fs::File;
use crate::error::Result;
use crate::op::{CompletionPayload, Op, OpDescriptor};
#[derive(Debug, Clone, Copy)]
pub struct SpliceResult {
pub bytes_transferred: usize,
}
pub struct Splice {
fd_in: File,
off_in: Option<u64>,
fd_out: File,
off_out: Option<u64>,
len: usize,
}
impl Splice {
pub fn new(
fd_in: File,
off_in: Option<u64>,
fd_out: File,
off_out: Option<u64>,
len: usize,
) -> Result<Self> {
if len == 0 {
return Err(crate::Error::invalid_config("splice length must be > 0"));
}
Ok(Self {
fd_in,
off_in,
fd_out,
off_out,
len,
})
}
}
impl Op for Splice {
type Output = SpliceResult;
fn name(&self) -> &'static str {
"splice"
}
fn into_descriptor(self) -> Result<OpDescriptor> {
Ok(OpDescriptor::Splice {
fd_in: self.fd_in,
off_in: self.off_in,
fd_out: self.fd_out,
off_out: self.off_out,
len: self.len,
})
}
fn map_completion(payload: CompletionPayload) -> Result<Self::Output> {
match payload {
CompletionPayload::Bytes(n) => Ok(SpliceResult {
bytes_transferred: n,
}),
other => Err(crate::error::Error::completion(
format!("splice received unexpected completion payload: {other:?}"),
"ensure the backend routes splice completions as byte-count payloads",
)),
}
}
}