taos_query/util/
inline_bytes.rs

1use std::fmt;
2
3#[repr(C)]
4#[repr(packed(1))]
5pub struct InlineBytes<T = u16> {
6    len: T,
7    data: [u8; 0],
8}
9
10macro_rules! _impl_inline_lines {
11    ($($ty:ty) *) => {
12        $(
13
14            impl fmt::Debug for InlineBytes<$ty> {
15                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16                    f.debug_struct("InlineBytes")
17                        .field("len", &self.len())
18                        .field("data", &self.as_bytes())
19                        .finish()
20                }
21            }
22
23            impl fmt::Display for InlineBytes<$ty> {
24                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25                    f.write_str(&self.printable())
26                }
27            }
28
29            impl AsRef<[u8]> for InlineBytes<$ty> {
30                fn as_ref(&self) -> &[u8] {
31                    self.as_bytes()
32                }
33            }
34
35            impl InlineBytes<$ty> {
36                #[inline]
37                /// # Safety
38                ///
39                /// Do not use it directly.
40                pub unsafe fn from_ptr<'a>(ptr: *const u8) -> &'a Self {
41                    &*ptr.cast::<InlineBytes<$ty>>()
42                }
43
44                #[inline]
45                pub const fn as_ptr(&self) -> *const u8 {
46                    self.data.as_ptr()
47                }
48                #[inline]
49                pub fn as_mut_ptr(&mut self) -> *mut u8 {
50                    self.data.as_mut_ptr()
51                }
52
53                #[inline]
54                #[rustversion::attr(nightly, const)]
55                pub fn as_bytes(&self) -> &[u8] {
56                    unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len()) }
57                }
58
59                #[inline]
60                pub fn printable(&self) -> String {
61                    String::from_utf8(self.as_bytes().iter().flat_map(|b| b.escape_ascii().into_iter()).collect()).expect("")
62                }
63
64                #[inline]
65                pub const fn len(&self) -> usize {
66                    self.len as _
67                }
68
69                #[inline]
70                pub fn encode(v: &[u8]) -> Vec<u8> {
71                    let len = v.len() as $ty;
72                    let mut vec = Vec::with_capacity(v.len() + std::mem::size_of::<$ty>());
73                    vec.extend(len.to_le_bytes());
74                    vec.extend(v);
75                    vec
76                }
77            }
78        )*
79    };
80}
81_impl_inline_lines!(u8 u16 u32 u64 usize);
82
83macro_rules! _impl_test_inline_lines {
84    ($ty:ty, $bytes:literal) => {{
85        let bytes = $bytes;
86        let inline = unsafe { InlineBytes::<$ty>::from_ptr(bytes.as_ptr()) };
87        dbg!(inline);
88        assert_eq!(inline.len(), 4);
89        assert_eq!(inline.as_ref(), b"abcd");
90        assert_eq!(inline.to_string(), "abcd");
91        assert_eq!(InlineBytes::<$ty>::encode(b"abcd"), bytes);
92    }};
93}
94
95#[test]
96fn test_inline_lines() {
97    _impl_test_inline_lines!(u8, b"\x04abcd");
98    _impl_test_inline_lines!(u16, b"\x04\x00abcd");
99    _impl_test_inline_lines!(u32, b"\x04\x00\x00\x00abcd");
100    _impl_test_inline_lines!(u64, b"\x04\x00\x00\x00\x00\x00\x00\x00abcd");
101}