use std::{
future::{Future, IntoFuture},
io::{self},
os::fd::AsFd,
pin::Pin,
task::{Context, Poll, ready},
};
use compio_driver::{SharedFd, ToSharedFd, op::Splice as SpliceOp};
use compio_runtime::Submit;
pub fn splice<I: AsFd + 'static, O: AsFd + 'static>(
fd_in: &impl ToSharedFd<I>,
fd_out: &impl ToSharedFd<O>,
len: usize,
) -> Splice<I, O> {
Splice {
fd_in: fd_in.to_shared_fd(),
fd_out: fd_out.to_shared_fd(),
len,
offset_in: -1,
offset_out: -1,
flags: 0,
}
}
pub struct Splice<I, O> {
fd_in: SharedFd<I>,
fd_out: SharedFd<O>,
len: usize,
offset_in: i64,
offset_out: i64,
flags: u32,
}
impl<I, O> Splice<I, O> {
pub fn offset_in(mut self, offset: i64) -> Self {
self.offset_in = offset;
self
}
pub fn offset_out(mut self, offset: i64) -> Self {
self.offset_out = offset;
self
}
pub fn flags(mut self, flags: u32) -> Self {
self.flags = flags;
self
}
}
impl<I: AsFd + 'static, O: AsFd + 'static> IntoFuture for Splice<I, O> {
type IntoFuture = SpliceFuture<I, O>;
type Output = io::Result<usize>;
fn into_future(self) -> Self::IntoFuture {
let inner = compio_runtime::submit(SpliceOp::new(
self.fd_in,
self.offset_in,
self.fd_out,
self.offset_out,
self.len,
self.flags,
));
SpliceFuture { inner }
}
}
pin_project_lite::pin_project! {
pub struct SpliceFuture<I, O> where I : AsFd, O: AsFd {
#[pin]
inner: Submit<SpliceOp<SharedFd<I>, SharedFd<O>>>,
}
}
impl<I: AsFd + 'static, O: AsFd + 'static> Future for SpliceFuture<I, O> {
type Output = io::Result<usize>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let res = ready!(self.project().inner.poll(cx));
Poll::Ready(res.0)
}
}