taos_query/util/
inline_json.rs1use std::fmt;
2
3use super::Inlinable;
4
5#[repr(C)]
6#[repr(packed(1))]
7pub struct InlineJson<T = u16> {
8 len: T,
9 data: [u8; 0],
10}
11macro_rules! _impl_inline_str {
12 ($($ty:ty) *) => {
13 $(
14
15 impl fmt::Debug for InlineJson<$ty> {
16 #[inline]
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_struct("InlineJson")
19 .field("len", &self.len())
20 .field("data", &self.as_str())
21 .finish()
22 }
23 }
24
25 impl fmt::Display for InlineJson<$ty> {
26 #[inline]
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 f.write_str(self.as_str())
29 }
30 }
31
32 impl AsRef<str> for InlineJson<$ty> {
33 #[inline]
34 fn as_ref(&self) -> &str {
35 self.as_str()
36 }
37 }
38
39 impl Inlinable for InlineJson<$ty> {
40 #[inline]
41 fn write_inlined<W: std::io::Write>(&self, wtr: &mut W) -> std::io::Result<usize> {
42 let l = wtr.write(&self.len.to_le_bytes())?;
43 Ok(l + wtr.write(self.as_bytes())?)
44 }
45
46 #[inline]
47 fn read_inlined<R: std::io::Read>(_: &mut R) -> std::io::Result<Self> {
48 Err(std::io::Error::new(std::io::ErrorKind::Other, "can't read into a inlined string"))
49 }
50 }
51
52 impl InlineJson<$ty> {
53 #[inline]
54 pub unsafe fn from_ptr<'a>(ptr: *const u8) -> &'a Self {
57 &*ptr.cast::<InlineJson<$ty>>()
58 }
59
60 #[inline]
61 pub fn as_ptr(&self) -> *const u8 {
62 self.data.as_ptr()
63 }
64
65 #[inline]
66 #[rustversion::attr(nightly, const)]
67 pub fn as_bytes(&self) -> &[u8] {
68 unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len()) }
69 }
70
71 #[inline]
72 #[rustversion::attr(nightly, const)]
73 pub fn as_str(&self) -> &str {
74 unsafe { std::str::from_utf8_unchecked(self.as_bytes()) }
75 }
76
77 #[inline]
88 pub const fn len(&self) -> usize {
89 self.len as _
90 }
91 }
92 )*
93 };
94}
95_impl_inline_str!(u8 u16 u32 u64 usize);
96
97#[test]
98fn test_inline_str() {
99 let bytes =
101 b"\x18\0{\"a\":\"\xe6\xb6\x9b\xe6\x80\x9d\xf0\x9d\x84\x9e\xe6\x95\xb0\xe6\x8d\xae\"}";
102 let json = "{\"a\":\"涛思𝄞数据\"}";
103 let inline = unsafe { InlineJson::<u16>::from_ptr(bytes.as_ptr()) };
104 dbg!(inline);
105 assert_eq!(inline.len(), 24);
106 assert_eq!(inline.as_ref(), json);
107 assert_eq!(format!("{}", inline), json);
110 assert_eq!(inline.inlined(), bytes);
111 assert_eq!(inline.printable_inlined(), "\\x18\\x00{\\\"a\\\":\\\"\\xe6\\xb6\\x9b\\xe6\\x80\\x9d\\xf0\\x9d\\x84\\x9e\\xe6\\x95\\xb0\\xe6\\x8d\\xae\\\"}");
112}