1use std::fmt;
7use std::ops;
8use std::slice;
9
10use libc::{c_void, iovec, size_t};
11use serde::de::{self, Error};
12use serde::{Serialize, Serializer};
13
14use super::utils;
15
16#[derive(Clone)]
18pub struct Iovec(iovec);
19
20impl Iovec {
21 pub(crate) fn from_slice(buf: &[u8]) -> Self {
22 let iov_len = buf.len();
23 let iov_base = buf.as_ptr() as *mut c_void;
24 let iov = iovec { iov_base, iov_len };
25 iov.into()
26 }
27
28 pub(crate) fn from_slice_mut(buf: &mut [u8]) -> Self {
29 let iov_len = buf.len();
30 let iov_base = buf.as_mut_ptr() as *mut c_void;
31 let iov = iovec { iov_base, iov_len };
32 iov.into()
33 }
34
35 pub fn as_slice(&self) -> &[u8] {
37 unsafe { utils::iovec_as_slice(&self.0) }
38 }
39
40 pub fn as_static_slice(&self) -> &'static [u8] {
41 unsafe { utils::iovec_as_static_slice(self.0) }
42 }
43
44 pub fn as_iovec_mut(&self) -> iovec {
45 self.0
46 }
47}
48
49impl From<iovec> for Iovec {
50 #[inline]
51 fn from(iov: iovec) -> Self {
52 Self { 0: iov }
53 }
54}
55
56impl From<(*mut c_void, size_t)> for Iovec {
57 fn from((iov_base, iov_len): (*mut c_void, size_t)) -> Self {
58 iovec { iov_base, iov_len }.into()
59 }
60}
61
62impl<'a> From<&'a [u8]> for Iovec {
63 fn from(buf: &[u8]) -> Self {
64 Self::from_slice(buf)
65 }
66}
67
68impl<'a> From<&'a mut [u8]> for Iovec {
69 fn from(buf: &mut [u8]) -> Self {
70 Self::from_slice_mut(buf)
71 }
72}
73
74impl fmt::Debug for Iovec {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 let iov = self.0;
77 f.debug_struct("Element::Iovec")
78 .field("iov_base", &iov.iov_base)
79 .field("iov_len", &iov.iov_len)
80 .finish()
81 }
82}
83
84impl PartialEq for Iovec {
85 fn eq(&self, other: &Self) -> bool {
86 let (iov1, iov2) = (self.0, other.0);
87 iov1.iov_base == iov2.iov_base && iov1.iov_len == iov2.iov_len
88 }
89}
90
91impl ops::Deref for Iovec {
92 type Target = [u8];
93
94 fn deref(&self) -> &Self::Target {
95 self.as_slice()
96 }
97}
98
99unsafe impl Send for Iovec {}
100unsafe impl Sync for Iovec {}
101
102impl Serialize for Iovec {
103 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104 where
105 S: Serializer,
106 {
107 let iov = self.0;
108 let buf = unsafe {
109 let base = iov.iov_base as *const u8;
110 let len = iov.iov_len as usize;
111 slice::from_raw_parts(base, len)
112 };
113 serializer.serialize_bytes(buf)
114 }
115}
116
117impl<'de> de::Deserialize<'de> for Iovec {
118 fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
119 where
120 D: de::Deserializer<'de>,
121 {
122 Err(D::Error::custom("Cannot deserialize Element"))
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn element_iovec() {
132 let mut buf = [0x55; 1024];
133 let iov = buf.as_mut_ptr() as *mut c_void;
134 let len = buf.len();
135 let e1 = Iovec::from((iov, len));
136 let e2 = Iovec::from(buf.as_ref());
137 assert_eq!(e1, e2);
138 }
139
140 #[test]
141 fn element_debug() {
142 let iov = 0x7000_0d48_aef0 as *mut c_void;
143 let len = 512;
144 let e = Iovec::from((iov, len));
145 assert_eq!(
146 format!("{:?}", e),
147 "Element::Iovec { iov_base: 0x70000d48aef0, iov_len: 512 }"
148 );
149 }
150}