sark_json/segment/document/
value.rs1use o3::buffer::storage;
2
3use crate::{
4 Error, Token,
5 segment::{
6 Cursor, Stored, ValueKind,
7 input::{Input, Split},
8 state,
9 },
10};
11
12pub struct Value<'a, 'd> {
15 input: &'a Input<'d>,
16 value: &'a state::Value,
17}
18
19impl<'a, 'd> Value<'a, 'd> {
20 pub(super) fn new(input: &'a Input<'d>, value: &'a state::Value) -> Self {
21 Self { input, value }
22 }
23
24 pub fn is_null(&self) -> bool {
25 matches!(self.value.kind, ValueKind::Null)
26 }
27
28 pub fn u64(&self) -> crate::Result<u64> {
29 match self.value.kind {
30 ValueKind::Unsigned(value) => Ok(value),
31 _ => Err(Error::Invalid),
32 }
33 }
34
35 pub fn i64(&self) -> crate::Result<i64> {
36 self.value.kind.i64()
37 }
38
39 pub fn boolean(&self) -> crate::Result<bool> {
40 match self.value.kind {
41 ValueKind::True => Ok(true),
42 ValueKind::False => Ok(false),
43 _ => Err(Error::Invalid),
44 }
45 }
46
47 pub fn frame(&self) -> crate::Result<crate::Text<storage::Shared>> {
48 let shared = match self.value.kind {
49 ValueKind::String { escapes: 0 } => self.materialize(1, 1),
50 ValueKind::String { escapes: 1.. } => match &self.value.stored {
51 Stored::Decoded(decoded) => decoded.try_clone().map_err(Error::Retain),
52 _ => Err(Error::Invalid),
53 },
54 _ => Err(Error::Invalid),
55 };
56 shared.map(crate::Text::admitted)
57 }
58
59 pub fn plain(&self) -> crate::Result<crate::Plain<storage::Shared>> {
60 let shared = match self.value.kind {
61 ValueKind::String { escapes: 0 } => self.materialize(1, 1),
62 _ => Err(Error::Invalid),
63 };
64 shared.map(crate::Plain::admitted)
65 }
66
67 pub fn raw(&self) -> crate::Result<crate::Raw<storage::Shared>> {
68 self.materialize(0, 0).map(crate::Raw::admitted)
69 }
70
71 pub fn inline_plain<const N: usize>(&self) -> crate::Result<crate::Plain<Token<N>>> {
72 let token = match self.value.kind {
73 ValueKind::String { escapes: 0 } => self.inline(1, 1),
74 _ => Err(Error::Invalid),
75 };
76 token.map(crate::Plain::admitted)
77 }
78
79 pub fn inline_raw<const N: usize>(&self) -> crate::Result<crate::Raw<Token<N>>> {
80 self.inline(0, 0).map(crate::Raw::admitted)
81 }
82
83 pub(super) fn split(&self) -> crate::Result<Split<'d>> {
84 let Stored::Segments(range) = &self.value.stored else {
85 return Err(Error::Invalid);
86 };
87 if !matches!(self.value.kind, ValueKind::Compound) {
88 return Err(Error::Invalid);
89 }
90 Split::new(self.input, range.clone())
91 }
92
93 fn materialize(&self, head: usize, tail: usize) -> crate::Result<storage::Shared> {
94 match &self.value.stored {
95 Stored::Bytes(range) | Stored::Frame(range) | Stored::Segments(range) => {
96 self.input.project(range.start + head..range.end - tail)
97 }
98 Stored::Copied(shared) => shared
99 .try_get(head..shared.len() - tail)
100 .map_err(Error::Retain)?
101 .ok_or(Error::Invalid),
102 _ => Err(Error::Invalid),
103 }
104 }
105
106 fn inline<const N: usize>(&self, head: usize, tail: usize) -> crate::Result<Token<N>> {
107 const { assert!(N <= u8::MAX as usize) }
108 match &self.value.stored {
109 Stored::Bytes(range) | Stored::Frame(range) | Stored::Segments(range) => {
110 let mut token = Token::new();
111 let start = range.start + head;
112 let end = range.end - tail;
113 let mut cursor = Cursor::at(self.input, start).ok_or(Error::Invalid)?;
114 while cursor.absolute < end {
115 let (byte, advance) = cursor.read(self.input).ok_or(Error::Invalid)?;
116 token.push(byte)?;
117 cursor.advance(advance);
118 }
119 Ok(token)
120 }
121 Stored::Copied(shared) => {
122 let mut token = Token::new();
123 let end = shared.len() - tail;
124 for byte in shared.as_slice().get(head..end).ok_or(Error::Invalid)? {
125 token.push(*byte)?;
126 }
127 Ok(token)
128 }
129 _ => Err(Error::Invalid),
130 }
131 }
132}