Skip to main content

sark_json/bytes/
mod.rs

1use std::borrow;
2
3pub(crate) mod proofs;
4pub(crate) mod seals;
5
6use o3::{buffer::storage, mem::Rejected};
7
8/// Admits words without escapes, optionally checking ASCII and control bytes.
9/// Cross-byte borrows only mark lanes after a matching byte.
10#[inline]
11pub(crate) fn is_plain(word: u64, ascii: bool, control: bool) -> bool {
12    const HIGH: u64 = 0x8080_8080_8080_8080;
13    const ONES: u64 = 0x0101_0101_0101_0101;
14    let quote = word ^ u64::from_ne_bytes([b'"'; 8]);
15    let slash = word ^ u64::from_ne_bytes([b'\\'; 8]);
16    let control = if control {
17        word.wrapping_sub(u64::from_ne_bytes([0x20; 8])) & !word
18    } else {
19        0
20    };
21    let quote = quote.wrapping_sub(ONES) & !quote;
22    let slash = slash.wrapping_sub(ONES) & !slash;
23    (control | quote | slash | if ascii { word } else { 0 }) & HIGH == 0
24}
25
26/// JSON bytes that borrow the request when possible and own only decoded escapes.
27#[repr(transparent)]
28#[derive(Debug)]
29pub struct Bytes<'req>(borrow::Cow<'req, [u8]>);
30
31impl<'req> Bytes<'req> {
32    #[must_use]
33    pub fn borrowed(bytes: &'req [u8]) -> Self {
34        Self(borrow::Cow::Borrowed(bytes))
35    }
36
37    #[must_use]
38    pub fn owned(bytes: Vec<u8>) -> Self {
39        Self(borrow::Cow::Owned(bytes))
40    }
41
42    pub fn as_slice(&self) -> &[u8] {
43        self.0.as_ref()
44    }
45
46    pub fn len(&self) -> usize {
47        self.as_slice().len()
48    }
49
50    pub fn is_empty(&self) -> bool {
51        self.as_slice().is_empty()
52    }
53
54    /// Transfers owned bytes or copies a borrowed view, returning the input on failure.
55    pub fn try_share(mut self) -> Result<storage::Shared, Rejected<Self, storage::AllocError>> {
56        let result = match &mut self.0 {
57            borrow::Cow::Borrowed(bytes) => storage::Shared::try_copy(bytes),
58            borrow::Cow::Owned(bytes) => {
59                storage::Shared::try_from(bytes).map_err(storage::AllocError::Exhausted)
60            }
61        };
62        result.map_err(|error| Rejected::new(self, error))
63    }
64}
65
66impl AsRef<[u8]> for Bytes<'_> {
67    fn as_ref(&self) -> &[u8] {
68        self.as_slice()
69    }
70}