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