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