1use std::{
4 future::{Future, IntoFuture},
5 io::{self},
6 os::fd::AsFd,
7 pin::Pin,
8 task::{Context, Poll, ready},
9};
10
11use compio_driver::{SharedFd, ToSharedFd, op::Splice as SpliceOp};
12use compio_runtime::Submit;
13
14pub fn splice<I: AsFd + 'static, O: AsFd + 'static>(
41 fd_in: &impl ToSharedFd<I>,
42 fd_out: &impl ToSharedFd<O>,
43 len: usize,
44) -> Splice<I, O> {
45 Splice {
46 fd_in: fd_in.to_shared_fd(),
47 fd_out: fd_out.to_shared_fd(),
48 len,
49 offset_in: -1,
50 offset_out: -1,
51 flags: 0,
52 }
53}
54
55pub struct Splice<I, O> {
57 fd_in: SharedFd<I>,
58 fd_out: SharedFd<O>,
59 len: usize,
60 offset_in: i64,
61 offset_out: i64,
62 flags: u32,
63}
64
65impl<I, O> Splice<I, O> {
66 pub fn offset_in(mut self, offset: i64) -> Self {
68 self.offset_in = offset;
69 self
70 }
71
72 pub fn offset_out(mut self, offset: i64) -> Self {
74 self.offset_out = offset;
75 self
76 }
77
78 pub fn flags(mut self, flags: u32) -> Self {
80 self.flags = flags;
81 self
82 }
83}
84
85impl<I: AsFd + 'static, O: AsFd + 'static> IntoFuture for Splice<I, O> {
86 type IntoFuture = SpliceFuture<I, O>;
87 type Output = io::Result<usize>;
88
89 fn into_future(self) -> Self::IntoFuture {
90 let inner = compio_runtime::submit(SpliceOp::new(
91 self.fd_in,
92 self.offset_in,
93 self.fd_out,
94 self.offset_out,
95 self.len,
96 self.flags,
97 ));
98 SpliceFuture { inner }
99 }
100}
101
102pin_project_lite::pin_project! {
103 pub struct SpliceFuture<I, O> where I : AsFd, O: AsFd {
105 #[pin]
106 inner: Submit<SpliceOp<SharedFd<I>, SharedFd<O>>>,
107 }
108}
109
110impl<I: AsFd + 'static, O: AsFd + 'static> Future for SpliceFuture<I, O> {
111 type Output = io::Result<usize>;
112
113 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
114 let res = ready!(self.project().inner.poll(cx));
115 Poll::Ready(res.0)
116 }
117}