taos_query/util/
inline_json.rs

1use 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                /// # Safety
55                ///
56                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                /// Parse inline bytes to json value.
78                ///
79                /// # Panic
80                ///
81                /// It will panic when the inner bytes is not valid to parse as json.
82                // pub fn as_json(&self) -> simd_json::BorrowedValue {
83                //     let slice = unsafe { std::slice::from_raw_parts_mut(self.data.as_ptr() as *mut u8, self.len()) };
84                //     simd_json::to_borrowed_value(slice).unwrap()
85                // }
86
87                #[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    // use simd_json::Writable;
100    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    // dbg!(inline.as_json());
108    // assert_eq!(format!("{}", inline.as_json().encode()), json);
109    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}