use crate::{
runtime::driver::op::{CancelData, Cancellable, Completable, CqeResult, Op},
util::as_ref::OwnedBuf,
};
use io_uring::{opcode, types};
use std::{
io,
os::fd::{AsRawFd, OwnedFd},
};
#[derive(Debug)]
pub(crate) struct Write {
buf: OwnedBuf,
fd: OwnedFd,
}
impl Completable for Write {
type Output = (u32, OwnedBuf, OwnedFd);
fn complete(self, cqe: CqeResult) -> io::Result<Self::Output> {
Ok((cqe.result?, self.buf, self.fd))
}
}
impl Cancellable for Write {
fn cancel(self) -> CancelData {
CancelData::Write(self)
}
}
impl Op<Write> {
pub(crate) fn write_at(
fd: OwnedFd,
buf: OwnedBuf,
buf_offset: usize,
file_offset: u64,
) -> io::Result<Self> {
let len = u32::try_from(buf.as_ref().len() - buf_offset).unwrap_or(u32::MAX);
let ptr = buf.as_ref()[buf_offset..buf_offset + len as usize].as_ptr();
let sqe = opcode::Write::new(types::Fd(fd.as_raw_fd()), ptr, len)
.offset(file_offset)
.build();
let op = unsafe { Op::new(sqe, Write { buf, fd }) };
Ok(op)
}
}