hive_router_plan_executor/response/
value.rs1use core::fmt;
2use hive_router_query_planner::ast::selection_item::SelectionItem;
3use serde::{
4 de::{self, Deserializer, MapAccess, SeqAccess, Visitor},
5 ser::{SerializeMap, SerializeSeq},
6};
7use sonic_rs::{JsonNumberTrait, ValueRef};
8use std::{
9 fmt::Display,
10 hash::{Hash, Hasher},
11};
12use xxhash_rust::xxh3::Xxh3;
13
14use crate::{introspection::schema::PossibleTypes, utils::consts::TYPENAME_FIELD_NAME};
15
16#[derive(Clone)]
17pub enum Value<'a> {
18 Null,
19 F64(f64),
20 I64(i64),
21 U64(u64),
22 Bool(bool),
23 String(&'a str),
24 Array(Vec<Value<'a>>),
25 Object(Vec<(&'a str, Value<'a>)>),
26}
27
28impl Hash for Value<'_> {
29 fn hash<H: Hasher>(&self, state: &mut H) {
30 match self {
31 Value::Null => 0.hash(state),
32 Value::F64(f) => f.to_bits().hash(state),
33 Value::I64(i) => i.hash(state),
34 Value::U64(u) => u.hash(state),
35 Value::Bool(b) => b.hash(state),
36 Value::String(s) => s.hash(state),
37 Value::Array(arr) => arr.hash(state),
38 Value::Object(obj) => obj.hash(state),
39 }
40 }
41}
42
43impl<'a> Value<'a> {
44 pub fn take_entities<'b: 'a>(&'a mut self) -> Option<Vec<Value<'a>>> {
45 match self {
46 Value::Object(data) => {
47 if let Ok(entities_idx) = data.binary_search_by_key(&"_entities", |(k, _)| *k) {
48 if let Value::Array(arr) = data.remove(entities_idx).1 {
49 return Some(arr);
50 }
51 }
52 None
53 }
54 _ => None,
55 }
56 }
57
58 pub fn to_hash(
59 &self,
60 selection_items: &[SelectionItem],
61 possible_types: &PossibleTypes,
62 ) -> u64 {
63 let mut hasher = Xxh3::new();
64 self.hash_with_requires(&mut hasher, selection_items, possible_types);
65 hasher.finish()
66 }
67
68 fn hash_with_requires<H: Hasher>(
69 &self,
70 state: &mut H,
71 selection_items: &[SelectionItem],
72 possible_types: &PossibleTypes,
73 ) {
74 if selection_items.is_empty() {
75 self.hash(state);
76 return;
77 }
78
79 match self {
80 Value::Object(obj) => {
81 Value::hash_object_with_requires(state, obj, selection_items, possible_types);
82 }
83 Value::Array(arr) => {
84 for item in arr {
85 item.hash_with_requires(state, selection_items, possible_types);
86 }
87 }
88 _ => {
89 self.hash(state);
90 }
91 }
92 }
93
94 fn hash_object_with_requires<H: Hasher>(
95 state: &mut H,
96 obj: &[(&'a str, Value<'a>)],
97 selection_items: &[SelectionItem],
98 possible_types: &PossibleTypes,
99 ) {
100 for item in selection_items {
101 match item {
102 SelectionItem::Field(field_selection) => {
103 let field_name = &field_selection.name;
104 if let Ok(idx) = obj.binary_search_by_key(&field_name.as_str(), |(k, _)| k) {
105 let (key, value) = &obj[idx];
106 key.hash(state);
107 value.hash_with_requires(
108 state,
109 &field_selection.selections.items,
110 possible_types,
111 );
112 }
113 }
114 SelectionItem::InlineFragment(inline_fragment) => {
115 let type_condition = &inline_fragment.type_condition;
116 let type_name = obj
117 .binary_search_by_key(&TYPENAME_FIELD_NAME, |(k, _)| k)
118 .ok()
119 .and_then(|idx| obj[idx].1.as_str())
120 .unwrap_or(type_condition);
121
122 if possible_types.entity_satisfies_type_condition(type_name, type_condition) {
123 Value::hash_object_with_requires(
124 state,
125 obj,
126 &inline_fragment.selections.items,
127 possible_types,
128 );
129 }
130 }
131 SelectionItem::FragmentSpread(_) => {
132 unreachable!("Fragment spreads should not exist in FetchNode::requires.")
133 }
134 }
135 }
136 }
137
138 pub fn from(json: ValueRef<'a>) -> Value<'a> {
139 match json {
140 ValueRef::Null => Value::Null,
141 ValueRef::Bool(b) => Value::Bool(b),
142 ValueRef::String(s) => Value::String(s),
143 ValueRef::Number(num) => {
144 if let Some(num) = num.as_f64() {
145 return Value::F64(num);
146 }
147
148 if let Some(num) = num.as_i64() {
149 return Value::I64(num);
150 }
151
152 if let Some(num) = num.as_u64() {
153 return Value::U64(num);
154 }
155
156 Value::Null
157 }
158 ValueRef::Array(arr) => {
159 let mut vec = Vec::with_capacity(arr.len());
160 vec.extend(arr.iter().map(|v| Value::from(v.as_ref())));
161 Value::Array(vec)
162 }
163 ValueRef::Object(obj) => {
164 let mut vec = Vec::with_capacity(obj.len());
165 vec.extend(obj.iter().map(|(k, v)| (k, Value::from(v.as_ref()))));
166 vec.sort_unstable_by_key(|(k, _)| *k);
167 Value::Object(vec)
168 }
169 }
170 }
171
172 pub fn as_object(&self) -> Option<&Vec<(&'a str, Value<'a>)>> {
173 match self {
174 Value::Object(obj) => Some(obj),
175 _ => None,
176 }
177 }
178
179 pub fn as_str(&self) -> Option<&str> {
180 match self {
181 Value::String(s) => Some(s),
182 _ => None,
183 }
184 }
185
186 pub fn is_null(&self) -> bool {
187 matches!(self, Value::Null)
188 }
189
190 pub fn is_object(&self) -> bool {
191 matches!(self, Value::Object(_))
192 }
193
194 #[inline]
195 pub fn estimate_size(&self) -> usize {
196 match self {
197 Value::String(s) => key_size(s),
198 Value::Object(obj) => {
199 let mut total = 0usize;
200 for (k, v) in obj.iter() {
201 total += key_size(k);
202 total += v.estimate_size();
203 }
204 let len = obj.len();
206 total + 2 + len + len.saturating_sub(1)
207 }
208 Value::Bool(_) => 5, Value::Null => 4,
210 Value::Array(arr) => {
211 let mut total = 0usize;
212 for v in arr.iter() {
213 total += v.estimate_size();
214 }
215 let len = arr.len();
217 total + 2 + len.saturating_sub(1)
218 }
219 Value::F64(_) => 25, Value::I64(n) => i64_len(*n),
221 Value::U64(n) => u64_len(*n),
222 }
223 }
224}
225
226pub trait ValueRefExt {
228 fn to_data<'a>(&'a self) -> Option<ValueRef<'a>>;
229 fn to_entities<'a>(&'a self) -> Option<Vec<ValueRef<'a>>>;
230}
231
232impl ValueRefExt for ValueRef<'_> {
234 fn to_data<'a>(&'a self) -> Option<ValueRef<'a>> {
235 match self {
236 ValueRef::Object(obj) => obj.get(&"data").map(|v| v.as_ref()),
237 _ => None,
238 }
239 }
240
241 fn to_entities<'a>(&'a self) -> Option<Vec<ValueRef<'a>>> {
242 match self.to_data().unwrap() {
243 ValueRef::Object(obj) => obj.get(&"_entities").and_then(|v| match v.as_ref() {
244 ValueRef::Array(arr) => Some(arr.iter().map(|v| v.as_ref()).collect()),
245 _ => None,
246 }),
247 _ => None,
248 }
249 }
250}
251
252impl Display for Value<'_> {
253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 match self {
255 Value::Null => write!(f, "null"),
256 Value::Bool(b) => write!(f, "{}", b),
257 Value::String(s) => write!(f, "\"{}\"", s),
258 Value::F64(n) => write!(f, "{}", n),
259 Value::U64(n) => write!(f, "{}", n),
260 Value::I64(n) => write!(f, "{}", n),
261 Value::Array(arr) => {
262 write!(f, "[")?;
263 for (i, v) in arr.iter().enumerate() {
264 if i > 0 {
265 write!(f, ", ")?;
266 }
267 write!(f, "{}", v)?;
268 }
269 write!(f, "]")
270 }
271 Value::Object(obj) => {
272 write!(f, "{{")?;
273 for (i, (k, v)) in obj.iter().enumerate() {
274 if i > 0 {
275 write!(f, ", ")?;
276 }
277 write!(f, "\"{}\": {}", k, v)?;
278 }
279 write!(f, "}}")
280 }
281 }
282 }
283}
284
285struct ValueVisitor<'a> {
286 _marker: std::marker::PhantomData<&'a ()>,
288}
289
290impl<'de> de::Deserialize<'de> for Value<'de> {
291 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
292 where
293 D: Deserializer<'de>,
294 {
295 deserializer.deserialize_any(ValueVisitor {
296 _marker: std::marker::PhantomData,
297 })
298 }
299}
300
301impl<'de> Visitor<'de> for ValueVisitor<'de> {
302 type Value = Value<'de>;
303
304 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
305 formatter.write_str("any valid JSON value")
306 }
307
308 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
309 Ok(Value::Bool(value))
310 }
311
312 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
313 Ok(Value::I64(value))
314 }
315
316 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
317 Ok(Value::U64(value))
318 }
319
320 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> {
321 Ok(Value::F64(value))
322 }
323
324 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
326 where
327 E: de::Error,
328 {
329 Ok(Value::String(value))
330 }
331
332 fn visit_unit<E>(self) -> Result<Self::Value, E> {
333 Ok(Value::Null)
334 }
335
336 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
338 where
339 A: SeqAccess<'de>,
340 {
341 let mut elements = Vec::with_capacity(seq.size_hint().unwrap_or(0));
342 while let Some(elem) = seq.next_element()? {
343 elements.push(elem);
344 }
345 Ok(Value::Array(elements))
346 }
347
348 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
350 where
351 M: MapAccess<'de>,
352 {
353 let mut entries = Vec::with_capacity(map.size_hint().unwrap_or(0));
354 while let Some((key, value)) = map.next_entry()? {
355 entries.push((key, value));
356 }
357 entries.sort_unstable_by_key(|(k, _)| *k);
359 Ok(Value::Object(entries))
360 }
361}
362
363impl serde::Serialize for Value<'_> {
364 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
365 where
366 S: serde::Serializer,
367 {
368 match self {
369 Value::Null => serializer.serialize_unit(),
370 Value::Bool(b) => serializer.serialize_bool(*b),
371 Value::I64(n) => serializer.serialize_i64(*n),
372 Value::U64(n) => serializer.serialize_u64(*n),
373 Value::F64(n) => serializer.serialize_f64(*n),
374 Value::String(s) => serializer.serialize_str(s),
375 Value::Array(arr) => {
376 let mut seq = serializer.serialize_seq(Some(arr.len()))?;
377 for v in arr {
378 seq.serialize_element(v)?;
379 }
380 seq.end()
381 }
382 Value::Object(obj) => {
383 let mut map = serializer.serialize_map(Some(obj.len()))?;
384 for (k, v) in obj {
385 map.serialize_entry(k, v)?;
386 }
387 map.end()
388 }
389 }
390 }
391}
392#[inline]
393fn key_size(key: &str) -> usize {
394 key.len() + 2 }
396
397#[inline]
399fn u64_len(n: u64) -> usize {
400 if n == 0 {
401 return 1;
402 }
403 n.ilog10() as usize + 1
404}
405
406#[inline]
408fn i64_len(n: i64) -> usize {
409 if n == 0 {
410 return 1;
411 }
412 let len = if n.is_negative() { 1 } else { 0 };
413 len + n.unsigned_abs().ilog10() as usize + 1
414}