1use alloc::{boxed::Box, rc::Rc, string::String, vec::Vec};
4use core::fmt::Debug;
5
6use serde::{Deserialize, Serialize};
7
8use super::*;
9use inner::StrBufferInner;
10
11#[cfg(all(not(feature = "std"), not(feature = "no-std-lock")))]
12compile_error!("One of the `std` or `no-std-lock` features should be enabled");
13
14pub(super) enum SerdeThreadGlobalState {
22 None,
23 Ser(SerdeThreadGlobalStateSer),
24 De(SerdeThreadGlobalStateDe),
25 DePrepare {
26 zero_copy: Box<dyn 'static + FnOnce()>,
27 },
28}
29
30pub(super) struct SerdeThreadGlobalStateSer {
31 str_buffer: Rc<StrBufferInner>,
32 offset_gen: Vec<usize>,
33 offsets: Option<alloc::vec::IntoIter<usize>>,
34}
35
36pub(super) struct SerdeThreadGlobalStateDe {
37 str_buffer: Rc<StrBufferInner>,
38 pub(super) zero_copy: Option<Box<dyn 'static + FnOnce()>>,
39}
40
41unsafe impl Send for SerdeThreadGlobalState {}
43unsafe impl Sync for SerdeThreadGlobalState {}
44
45impl SerdeThreadGlobalState {
46 #[cfg(feature = "std")]
47 #[allow(dead_code)]
48 fn get<R>(f: impl FnOnce(&mut SerdeThreadGlobalState) -> R) -> R {
49 thread_local! {
50 static SERDE_THREAD_GLOBAL_STATE: RefCell<SerdeThreadGlobalState> = const { core::cell::RefCell::new(SerdeThreadGlobalState::None) };
51 }
52 SERDE_THREAD_GLOBAL_STATE.with(|x| {
53 let mut x = x.borrow_mut();
54 f(&mut x)
55 })
56 }
57
58 #[cfg(all(not(feature = "std"), feature = "no-std-lock"))]
59 #[allow(dead_code)]
60 fn get<R>(f: impl FnOnce(&mut SerdeThreadGlobalState) -> R) -> R {
61 static SERDE_THREAD_GLOBAL_STATE: spin::Lazy<spin::Mutex<SerdeThreadGlobalState>> =
62 spin::Lazy::new(|| spin::Mutex::new(SerdeThreadGlobalState::None));
63 f(&mut SERDE_THREAD_GLOBAL_STATE.lock())
64 }
65
66 #[allow(dead_code)]
67 pub(super) fn ser<R>(ser: SerdeThreadGlobalStateSer, f: impl FnOnce() -> R) -> R {
68 Self::get(|state| {
69 let SerdeThreadGlobalState::None = state else {
70 panic!("Invalid SerdeThreadGlobalState state");
71 };
72 *state = SerdeThreadGlobalState::Ser(ser);
73 });
74 let ret = f();
75 Self::get(|state| {
76 *state = SerdeThreadGlobalState::None;
77 });
78 ret
79 }
80
81 #[allow(dead_code)]
82 pub(super) fn get_ser<R>(f: impl FnOnce(&mut SerdeThreadGlobalStateSer) -> R) -> R {
83 Self::get(|state| {
84 let SerdeThreadGlobalState::Ser(ser) = state else {
85 panic!("Invalid SerdeThreadGlobalState state");
86 };
87 f(ser)
88 })
89 }
90
91 #[allow(dead_code)]
92 pub(super) fn de_prepare<R>(
93 zero_copy: Box<dyn 'static + FnOnce()>,
94 f: impl FnOnce() -> R,
95 ) -> R {
96 Self::get(|state| {
97 let SerdeThreadGlobalState::None = state else {
98 panic!("Invalid SerdeThreadGlobalState state");
99 };
100 *state = SerdeThreadGlobalState::DePrepare { zero_copy };
101 });
102 let ret = f();
103 Self::get(|state| {
104 *state = SerdeThreadGlobalState::None;
105 });
106 ret
107 }
108
109 #[allow(dead_code)]
110 pub(super) fn de<R>(mut de: SerdeThreadGlobalStateDe, f: impl FnOnce() -> R) -> R {
111 Self::get(|state| {
112 let old_state = core::mem::replace(state, SerdeThreadGlobalState::None);
113 de.zero_copy = match old_state {
114 SerdeThreadGlobalState::None => None,
115 SerdeThreadGlobalState::DePrepare { zero_copy } => Some(zero_copy),
116 _ => panic!("Invalid SerdeThreadGlobalState state"),
117 };
118 *state = SerdeThreadGlobalState::De(de);
119 });
120 let ret = f();
121 Self::get(|state| {
122 *state = SerdeThreadGlobalState::None;
123 });
124 ret
125 }
126
127 #[allow(dead_code)]
128 pub(super) fn get_de<R>(f: impl FnOnce(&mut SerdeThreadGlobalStateDe) -> R) -> R {
129 Self::get(|state| {
130 let SerdeThreadGlobalState::De(de) = state else {
131 panic!("Invalid SerdeThreadGlobalState state");
132 };
133 f(de)
134 })
135 }
136
137 #[allow(dead_code)]
138 pub(super) fn get_de_optional<R>(
139 f: impl FnOnce(Option<&mut SerdeThreadGlobalStateDe>) -> R,
140 ) -> R {
141 Self::get(|state| {
142 if let SerdeThreadGlobalState::De(de) = state {
143 f(Some(de))
144 } else {
145 f(None)
146 }
147 })
148 }
149}
150
151pub(crate) fn str_buffer_de_env<R>(str_buffer: &StrBuffer, f: impl FnOnce() -> R) -> R {
152 SerdeThreadGlobalState::de(
153 SerdeThreadGlobalStateDe {
154 str_buffer: str_buffer.inner.clone(),
155 zero_copy: None,
156 },
157 f,
158 )
159}
160
161pub(crate) fn str_buffer_ser_env<R, T>(
162 first_gen_f: impl FnOnce() -> T,
163 final_gen_f: impl FnOnce(T, StrBuffer) -> R,
164) -> R {
165 SerdeThreadGlobalState::ser(
166 SerdeThreadGlobalStateSer {
167 str_buffer: Rc::new(StrBufferInner::new()),
168 offset_gen: vec![],
169 offsets: None,
170 },
171 || {
172 let r = first_gen_f();
173 let buf = SerdeThreadGlobalState::get_ser(|state| {
174 let buf = state.str_buffer.clone();
175 let offset_gen = core::mem::take(&mut state.offset_gen);
176 buf.freeze();
177 state.offsets = Some(offset_gen.into_iter());
178 buf
179 });
180 final_gen_f(r, StrBuffer { inner: buf })
181 },
182 )
183}
184
185pub(crate) mod inner {
186 use alloc::{boxed::Box, vec::Vec};
187 use core::cell::{Cell, UnsafeCell};
188
189 pub(crate) struct StrBufferInner {
190 writable: Cell<bool>,
191 static_borrowed: Option<Box<dyn 'static + FnOnce()>>,
192 buf: UnsafeCell<Vec<u8>>,
193 }
194
195 impl Drop for StrBufferInner {
196 fn drop(&mut self) {
197 if let Some(f) = self.static_borrowed.take() {
198 let buf = unsafe { &mut *self.buf.get() };
199 let mut empty = vec![];
200 core::mem::swap(&mut empty, buf);
201 let _ = Box::into_raw(empty.into_boxed_slice());
202 f();
203 }
204 }
205 }
206
207 impl core::fmt::Debug for StrBufferInner {
208 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
209 write!(
210 f,
211 "StrBufferInner {{ writable: {}, buf: [...] }}",
212 self.writable.get()
213 )
214 }
215 }
216
217 impl StrBufferInner {
218 pub(super) fn new() -> Self {
219 Self {
220 writable: Cell::new(true),
221 static_borrowed: None,
222 buf: UnsafeCell::new(vec![]),
223 }
224 }
225
226 pub(super) fn new_with_buf(buf: Vec<u8>) -> Self {
227 Self {
228 writable: Cell::new(false),
229 static_borrowed: None,
230 buf: UnsafeCell::new(buf),
231 }
232 }
233
234 pub(super) unsafe fn new_static_borrowed(
235 buf: *mut [u8],
236 drop_callback: Box<dyn 'static + FnOnce()>,
237 ) -> Self {
238 Self {
239 writable: Cell::new(false),
240 static_borrowed: Some(Box::new(drop_callback)),
241 buf: UnsafeCell::new(Box::from_raw(buf).into_vec()),
242 }
243 }
244
245 pub(super) fn freeze(&self) {
246 self.writable.set(false);
247 }
248
249 pub(super) fn append(&self, s: &str) -> usize {
250 if !self.writable.get() {
251 panic!("StrBuffer is not in writable stage");
252 }
253 let buf = unsafe { &mut *self.buf.get() };
254 let offset = buf.len();
255 buf.append(&mut Vec::from(s.as_bytes()));
256 offset
257 }
258
259 pub(super) fn read(&self) -> &[u8] {
260 if self.writable.get() {
261 panic!("StrBuffer is not in writable stage");
262 }
263 let buf = unsafe { &mut *self.buf.get() };
264 buf.as_slice()
265 }
266
267 pub(super) fn len(&self) -> usize {
268 let buf = unsafe { &mut *self.buf.get() };
269 buf.len()
270 }
271 }
272}
273
274#[repr(C)]
276#[derive(Debug, Clone)]
277pub struct StrBuffer {
278 inner: Rc<StrBufferInner>,
279}
280
281impl StrBuffer {
282 #[cfg(feature = "serialize")]
283 pub(crate) fn new() -> Self {
284 Self {
285 inner: Rc::new(StrBufferInner::new()),
286 }
287 }
288
289 pub(crate) fn new_with_buf(buf: Vec<u8>) -> Self {
290 Self {
291 inner: Rc::new(StrBufferInner::new_with_buf(buf)),
292 }
293 }
294
295 pub(crate) unsafe fn new_static_borrowed(
296 buf: *mut [u8],
297 drop_callback: Box<dyn 'static + FnOnce()>,
298 ) -> Self {
299 Self {
300 inner: Rc::new(StrBufferInner::new_static_borrowed(buf, drop_callback)),
301 }
302 }
303
304 #[cfg(feature = "serialize")]
305 pub(crate) fn freeze(&mut self) {
306 self.inner.freeze()
307 }
308
309 pub(crate) fn whole_buffer(&self) -> &[u8] {
310 self.inner.read()
311 }
312}
313
314#[repr(C)]
318#[derive(Clone)]
319pub struct StrRef {
320 offset: usize,
321 len: usize,
322 buf: Rc<StrBufferInner>,
323}
324
325impl StrRef {
326 pub fn as_slice<'a>(&'a self) -> &'a [u8] {
328 let buf = self.buf.read();
329 unsafe {
330 let ptr = (buf as *const [u8] as *const u8).add(self.offset);
331 core::slice::from_raw_parts::<'a, u8>(ptr, self.len)
332 }
333 }
334
335 pub fn as_str(&self) -> &str {
337 core::str::from_utf8(self.as_slice()).unwrap_or_default()
338 }
339
340 #[doc(hidden)]
341 pub unsafe fn as_str_unchecked(&self) -> &str {
344 core::str::from_utf8_unchecked(self.as_slice())
345 }
346
347 #[allow(clippy::inherent_to_string)]
349 pub fn to_string(&self) -> String {
350 String::from_utf8_lossy(self.as_slice()).into_owned()
351 }
352
353 pub fn equal(&self, s: &str) -> bool {
355 self.as_slice() == s.as_bytes()
356 }
357
358 #[doc(hidden)]
359 #[cfg(feature = "ffi")]
360 #[no_mangle]
361 pub extern "C" fn str_ptr(&self) -> *const u8 {
362 let buf = self.buf.read();
363 unsafe { (buf as *const [u8] as *const u8).add(self.offset) }
364 }
365
366 #[doc(hidden)]
367 #[cfg(feature = "ffi")]
368 #[no_mangle]
369 pub extern "C" fn str_len(&self) -> usize {
370 self.len
371 }
372}
373
374impl<T: alloc::string::ToString> From<T> for StrRef {
375 fn from(s: T) -> Self {
376 let s = s.to_string();
377 let len = s.len();
378 let buf = Rc::new(StrBufferInner::new_with_buf(s.into_bytes()));
379 Self {
380 offset: 0,
381 len,
382 buf,
383 }
384 }
385}
386
387impl Default for StrRef {
388 fn default() -> Self {
389 Self::from(String::new())
390 }
391}
392
393impl PartialEq for StrRef {
394 fn eq(&self, other: &Self) -> bool {
395 self.as_slice() == other.as_slice()
396 }
397}
398
399impl Serialize for StrRef {
400 fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
401 where
402 S: serde::Serializer,
403 {
404 let offset = SerdeThreadGlobalState::get_ser(|state| {
405 if let Some(offsets) = state.offsets.as_mut() {
406 offsets.next().unwrap_or_default()
407 } else {
408 let x = state.str_buffer.append(self.as_str());
409 state.offset_gen.push(x);
410 0
411 }
412 });
413 (offset, self.len).serialize(ser)
414 }
415}
416
417impl<'de> Deserialize<'de> for StrRef {
418 fn deserialize<D>(de: D) -> Result<Self, D::Error>
419 where
420 D: serde::Deserializer<'de>,
421 {
422 let buf = SerdeThreadGlobalState::get_de(|state| state.str_buffer.clone());
423 let (offset, len) = <(usize, usize)>::deserialize(de)?;
424 let offset = offset.min(buf.len());
425 Ok(Self { offset, len, buf })
426 }
427}
428impl Debug for StrRef {
429 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
430 write!(f, "{}", self.as_str())
431 }
432}
433#[cfg(debug_assertions)]
434impl crate::CompatibilityCheck for StrRef {
435 fn check() {}
436}