1use crate::typed_op::TypedOp;
2use crate::{BufResult, api::resource::Resource, buf::BufLike};
3
4pub struct Read<T>
5where
6 T: Send + Sync,
7{
8 res: Resource,
9 buf: Option<T>,
10}
11
12impl<T> Read<T>
13where
14 T: Send + Sync,
15{
16 pub(crate) fn new(res: Resource, mem: T) -> Self
18 where
19 T: BufLike,
20 {
21 Self { res, buf: Some(mem) }
22 }
23
24 pub fn to_op(mut self) -> crate::op::Op
25 where
26 T: BufLike + 'static,
27 {
28 let buffer = self.buf.take().expect("buffer already taken");
29 crate::op::Op::Read { fd: self.res, buffer: crate::op::OpBuf::new(buffer) }
30 }
31}
32
33impl<T> TypedOp for Read<T>
34where
35 T: BufLike + Send + Sync + 'static,
36{
37 type Result = BufResult<i32, T>;
38
39 fn into_op(&mut self) -> crate::op::Op {
40 let slice = self.buf.as_mut().expect("buffer not available").buf();
41 let ptr = slice.as_ptr() as *mut u8;
42 let len = slice.len();
43 crate::op::Op::Read {
44 fd: self.res.clone(),
45 buffer: crate::op::OpBuf::new(crate::op::RawBuf { ptr, len }),
46 }
47 }
48
49 fn extract_result(self, res: isize) -> Self::Result {
50 let buf = self.buf.expect("buffer not available");
51 if res < 0 {
52 (Err(std::io::Error::from_raw_os_error((-res) as i32)), buf)
54 } else {
55 (Ok(res as i32), buf.after(res as usize))
57 }
58 }
59
60 }