1use bytes::Bytes;
2use faststr::FastStr;
3
4use crate::{parser::as_str, util::private::Sealed};
5
6#[doc(hidden)]
8#[non_exhaustive]
9#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
10pub enum JsonSlice<'de> {
11 Raw(&'de [u8]),
12 FastStr(FastStr), }
14
15impl<'de> JsonSlice<'de> {
16 #[inline(always)]
17 pub(crate) unsafe fn as_faststr(&self) -> FastStr {
18 match self {
19 JsonSlice::Raw(sub) => FastStr::new(as_str(sub)),
20 JsonSlice::FastStr(f) => f.clone(),
21 }
22 }
23}
24
25impl Default for JsonSlice<'_> {
26 fn default() -> Self {
27 JsonSlice::Raw(&b"null"[..])
28 }
29}
30
31impl<'de> From<FastStr> for JsonSlice<'de> {
32 fn from(value: FastStr) -> Self {
33 JsonSlice::FastStr(value)
34 }
35}
36
37impl<'de> From<Bytes> for JsonSlice<'de> {
38 fn from(value: Bytes) -> Self {
39 JsonSlice::FastStr(unsafe { FastStr::from_bytes_unchecked(value) })
40 }
41}
42
43impl<'de> From<&'de [u8]> for JsonSlice<'de> {
44 fn from(value: &'de [u8]) -> Self {
45 JsonSlice::Raw(value)
46 }
47}
48
49impl<'de> From<&'de str> for JsonSlice<'de> {
50 fn from(value: &'de str) -> Self {
51 JsonSlice::Raw(value.as_bytes())
52 }
53}
54
55impl<'de> From<&'de String> for JsonSlice<'de> {
56 fn from(value: &'de String) -> Self {
57 JsonSlice::Raw(value.as_bytes())
58 }
59}
60
61impl From<String> for JsonSlice<'_> {
62 fn from(value: String) -> Self {
63 JsonSlice::FastStr(FastStr::new(value))
64 }
65}
66
67impl<'de> AsRef<[u8]> for JsonSlice<'de> {
68 fn as_ref(&self) -> &[u8] {
69 match self {
70 Self::Raw(r) => r,
71 Self::FastStr(s) => s.as_bytes(),
72 }
73 }
74}
75
76pub trait JsonInput<'de>: Sealed {
78 fn need_utf8_valid(&self) -> bool;
79 fn to_json_slice(&self) -> JsonSlice<'de>;
80 #[allow(clippy::wrong_self_convention)]
81 fn from_subset(&self, sub: &'de [u8]) -> JsonSlice<'de>;
82 fn to_u8_slice(&self) -> &'de [u8];
83}
84
85impl<'de> JsonInput<'de> for &'de [u8] {
86 fn need_utf8_valid(&self) -> bool {
87 true
88 }
89
90 fn to_json_slice(&self) -> JsonSlice<'de> {
91 JsonSlice::Raw(self)
92 }
93
94 fn from_subset(&self, sub: &'de [u8]) -> JsonSlice<'de> {
95 sub.into()
96 }
97
98 fn to_u8_slice(&self) -> &'de [u8] {
99 self
100 }
101}
102
103impl<'de> JsonInput<'de> for &'de str {
104 fn need_utf8_valid(&self) -> bool {
105 false
106 }
107 fn to_json_slice(&self) -> JsonSlice<'de> {
108 JsonSlice::Raw((*self).as_bytes())
109 }
110
111 fn from_subset(&self, sub: &'de [u8]) -> JsonSlice<'de> {
112 sub.into()
113 }
114
115 fn to_u8_slice(&self) -> &'de [u8] {
116 (*self).as_bytes()
117 }
118}
119
120impl<'de> JsonInput<'de> for &'de Bytes {
121 fn need_utf8_valid(&self) -> bool {
122 true
123 }
124
125 fn to_json_slice(&self) -> JsonSlice<'de> {
126 let bytes = self.as_ref();
127 let newed = self.slice_ref(bytes);
128 JsonSlice::FastStr(unsafe { FastStr::from_bytes_unchecked(newed) })
129 }
130
131 fn from_subset(&self, sub: &'de [u8]) -> JsonSlice<'de> {
132 self.slice_ref(sub).into()
133 }
134
135 fn to_u8_slice(&self) -> &'de [u8] {
136 (*self).as_ref()
137 }
138}
139
140impl<'de> JsonInput<'de> for &'de FastStr {
141 fn need_utf8_valid(&self) -> bool {
142 false
143 }
144
145 fn to_json_slice(&self) -> JsonSlice<'de> {
146 JsonSlice::FastStr((**self).clone())
147 }
148
149 fn from_subset(&self, sub: &'de [u8]) -> JsonSlice<'de> {
150 self.slice_ref(as_str(sub)).into()
151 }
152
153 fn to_u8_slice(&self) -> &'de [u8] {
154 (*self).as_ref()
155 }
156}
157
158impl<'de> JsonInput<'de> for &'de String {
159 fn need_utf8_valid(&self) -> bool {
160 false
161 }
162
163 fn to_json_slice(&self) -> JsonSlice<'de> {
164 JsonSlice::Raw(self.as_bytes())
165 }
166
167 fn from_subset(&self, sub: &'de [u8]) -> JsonSlice<'de> {
168 sub.into()
169 }
170
171 fn to_u8_slice(&self) -> &'de [u8] {
172 (*self).as_bytes()
173 }
174}