taos_query/util/
inline_bytes.rs1use 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 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}