simd_json/value/lazy/
trait_impls.rs

1use std::{
2    borrow::{Borrow, Cow},
3    hash::Hash,
4    io::{self, Write},
5};
6
7use value_trait::{
8    TryTypeError, ValueBuilder, ValueType,
9    base::{
10        TypedValue, ValueAsArray as _, ValueAsMutArray, ValueAsMutObject, ValueAsObject as _,
11        ValueAsScalar, ValueIntoString, Writable,
12    },
13    derived::{
14        ValueArrayTryAccess, ValueObjectAccessAsArray as _, ValueObjectAccessAsObject as _,
15        ValueObjectAccessAsScalar, ValueObjectAccessTryAsArray as _,
16        ValueObjectAccessTryAsObject as _, ValueObjectAccessTryAsScalar, ValueObjectTryAccess,
17        ValueTryAsScalar,
18    },
19};
20
21use crate::{borrowed, tape};
22
23use super::{Array, Object, Value};
24
25impl<'value> ValueBuilder<'value> for Value<'static, 'static, 'value> {
26    #[cfg_attr(not(feature = "no-inline"), inline)]
27    fn null() -> Self {
28        Value::Tape(tape::Value::null())
29    }
30    #[cfg_attr(not(feature = "no-inline"), inline)]
31    fn array_with_capacity(capacity: usize) -> Self {
32        Value::Value(Cow::Owned(borrowed::Value::array_with_capacity(capacity)))
33    }
34    #[cfg_attr(not(feature = "no-inline"), inline)]
35    fn object_with_capacity(capacity: usize) -> Self {
36        Value::Value(Cow::Owned(borrowed::Value::object_with_capacity(capacity)))
37    }
38}
39
40// TypedContainerValue
41impl<'tape, 'input> Value<'_, 'tape, 'input>
42where
43    'input: 'tape,
44{
45    /// returns true if the current value can be represented as an array
46    #[must_use]
47    pub fn is_array(&self) -> bool {
48        self.as_array().is_some()
49    }
50
51    /// returns true if the current value can be represented as an object
52    #[must_use]
53    pub fn is_object(&self) -> bool {
54        self.as_object().is_some()
55    }
56}
57
58impl ValueAsScalar for Value<'_, '_, '_> {
59    #[cfg_attr(not(feature = "no-inline"), inline)]
60    fn as_null(&self) -> Option<()> {
61        match &self {
62            Value::Tape(tape) => tape.as_null(),
63            Value::Value(value) => value.as_null(),
64        }
65    }
66
67    #[cfg_attr(not(feature = "no-inline"), inline)]
68    fn as_bool(&self) -> Option<bool> {
69        match &self {
70            Value::Tape(tape) => tape.as_bool(),
71            Value::Value(value) => value.as_bool(),
72        }
73    }
74
75    #[cfg_attr(not(feature = "no-inline"), inline)]
76    fn as_i64(&self) -> Option<i64> {
77        match &self {
78            Value::Tape(tape) => tape.as_i64(),
79            Value::Value(value) => value.as_i64(),
80        }
81    }
82
83    #[cfg_attr(not(feature = "no-inline"), inline)]
84    fn as_i128(&self) -> Option<i128> {
85        match &self {
86            Value::Tape(tape) => tape.as_i128(),
87            Value::Value(value) => value.as_i128(),
88        }
89    }
90
91    #[cfg_attr(not(feature = "no-inline"), inline)]
92    fn as_u64(&self) -> Option<u64> {
93        match &self {
94            Value::Tape(tape) => tape.as_u64(),
95            Value::Value(value) => value.as_u64(),
96        }
97    }
98
99    #[cfg_attr(not(feature = "no-inline"), inline)]
100    fn as_u128(&self) -> Option<u128> {
101        match &self {
102            Value::Tape(tape) => tape.as_u128(),
103            Value::Value(value) => value.as_u128(),
104        }
105    }
106
107    #[cfg_attr(not(feature = "no-inline"), inline)]
108    fn as_f64(&self) -> Option<f64> {
109        match &self {
110            Value::Tape(tape) => tape.as_f64(),
111            Value::Value(value) => value.as_f64(),
112        }
113    }
114
115    #[cfg_attr(not(feature = "no-inline"), inline)]
116    fn cast_f64(&self) -> Option<f64> {
117        match &self {
118            Value::Tape(tape) => tape.cast_f64(),
119            Value::Value(value) => value.cast_f64(),
120        }
121    }
122
123    #[cfg_attr(not(feature = "no-inline"), inline)]
124    fn as_str(&self) -> Option<&str> {
125        match &self {
126            Value::Tape(tape) => tape.as_str(),
127            Value::Value(value) => value.as_str(),
128        }
129    }
130}
131
132impl<'value> ValueIntoString for Value<'_, '_, 'value> {
133    type String = Cow<'value, str>;
134
135    fn into_string(self) -> Option<<Self as ValueIntoString>::String> {
136        match self {
137            Value::Tape(tape) => tape.into_string().map(Cow::Borrowed),
138            // This is a bit complex but it allows us to avoid cloning
139            Value::Value(value) => match value {
140                Cow::Borrowed(value) => match value {
141                    #[cfg(feature = "beef")]
142                    borrowed::Value::String(s) => Some(s.clone().into()),
143                    #[cfg(not(feature = "beef"))]
144                    borrowed::Value::String(s) => Some(s.clone()),
145                    _ => None,
146                },
147                Cow::Owned(value) => match value {
148                    #[cfg(feature = "beef")]
149                    borrowed::Value::String(s) => Some(s.into()),
150                    #[cfg(not(feature = "beef"))]
151                    borrowed::Value::String(s) => Some(s),
152                    _ => None,
153                },
154            },
155        }
156    }
157}
158
159// impl<'tape, 'input> ValueIntoContainer for Value<'tape, 'input> {
160//     type Array = array::Array<'tape, 'input>;
161//     type Object = Object<'tape, 'input>;
162//     fn into_array(self) -> Option<Self::Array> {
163//         if let Some(Node::Array { count, .. }) = self.0.first() {
164//             // we add one element as we want to keep the array header
165//             let count = *count + 1;
166//             Some(Array(&self.0[..count]))
167//         } else {
168//             None
169//         }
170//     }
171
172//     fn into_object(self) -> Option<Self::Object> {
173//         if let Some(Node::Object { count, .. }) = self.0.first() {
174//             // we add one element as we want to keep the object header
175//             let count = *count + 1;
176//             Some(Object(&self.0[..count]))
177//         } else {
178//             None
179//         }
180//     }
181// }
182
183impl TypedValue for Value<'_, '_, '_> {
184    #[cfg_attr(not(feature = "no-inline"), inline)]
185    fn value_type(&self) -> ValueType {
186        match &self {
187            Value::Tape(tape) => tape.value_type(),
188            Value::Value(value) => value.value_type(),
189        }
190    }
191}
192
193// TryValueObjectAccess
194impl<'tape, 'input> Value<'_, 'tape, 'input> {
195    // type Key = &str;
196    // type Target = Value<'tape, 'input>;
197
198    /// Tries to get a value based on a key, returns a `TryTypeError` if the
199    /// current Value isn't an Object, returns `None` if the key isn't in the object
200    /// # Errors
201    /// if the value is not an object
202    pub fn try_get<Q>(&self, k: &Q) -> Result<Option<Value<'_, 'tape, 'input>>, TryTypeError>
203    where
204        str: Borrow<Q> + Hash + Eq,
205        for<'b> crate::cow::Cow<'b, str>: Borrow<Q>,
206        Q: ?Sized + Hash + Eq + Ord,
207    {
208        match self {
209            Value::Tape(tape) => Ok(tape.try_get(k)?.map(Value::Tape)),
210            Value::Value(value) => Ok(value.try_get(k)?.map(Cow::Borrowed).map(Value::Value)),
211        }
212    }
213}
214
215//TryValueArrayAccess
216impl<'tape, 'input> Value<'_, 'tape, 'input>
217where
218    'input: 'tape,
219{
220    /// Tries to get a value based on n index, returns a type error if the
221    /// current value isn't an Array, returns `None` if the index is out of bounds
222    /// # Errors
223    /// if the requested type doesn't match the actual type or the value is not an object
224    pub fn try_get_idx(&self, i: usize) -> Result<Option<Value<'_, 'tape, 'input>>, TryTypeError> {
225        match self {
226            Value::Tape(tape) => Ok(tape.try_get_idx(i)?.map(Value::Tape)),
227            Value::Value(value) => Ok(value.try_get_idx(i)?.map(Cow::Borrowed).map(Value::Value)),
228        }
229    }
230}
231
232// impl<'tape, 'value> ValueAsContainer for Value<'tape, 'value> {
233impl<'tape, 'input> Value<'_, 'tape, 'input>
234where
235    'input: 'tape,
236{
237    // type Array = array::Array<'tape, 'value>;
238    // type Object = Object<'tape, 'value>;
239
240    /// Tries to represent the value as an array and returns a reference to it
241    #[cfg_attr(not(feature = "no-inline"), inline)]
242    pub fn as_array(&self) -> Option<Array<'_, 'tape, 'input>> {
243        match self {
244            Value::Tape(tape) => tape.as_array().map(Array::Tape),
245            Value::Value(value) => value.as_array().map(Array::Value),
246        }
247    }
248
249    /// Tries to represent the value as an array and returns a reference to it
250    #[cfg_attr(not(feature = "no-inline"), inline)]
251    pub fn as_object(&self) -> Option<Object<'_, 'tape, 'input>> {
252        match self {
253            Value::Tape(tape) => tape.as_object().map(Object::Tape),
254            Value::Value(value) => value.as_object().map(Object::Value),
255        }
256    }
257}
258
259impl<'input> ValueAsMutArray for Value<'_, '_, 'input> {
260    type Array = Vec<borrowed::Value<'input>>;
261    #[cfg_attr(not(feature = "no-inline"), inline)]
262    fn as_array_mut(&mut self) -> Option<&mut Vec<borrowed::Value<'input>>> {
263        self.as_mut().as_array_mut()
264    }
265}
266impl<'input> ValueAsMutObject for Value<'_, '_, 'input> {
267    type Object = super::borrowed::Object<'input>;
268    #[cfg_attr(not(feature = "no-inline"), inline)]
269    fn as_object_mut(&mut self) -> Option<&mut super::borrowed::Object<'input>> {
270        self.as_mut().as_object_mut()
271    }
272}
273
274// ContainerValueTryAs (needed as we don't have ValueAsContainer)
275impl<'tape, 'input> Value<'_, 'tape, 'input> {
276    /// Tries to represent the value as an array and returns a reference to it
277    /// # Errors
278    /// if the requested type doesn't match the actual type
279    pub fn try_as_array(&self) -> Result<Array<'_, 'tape, 'input>, TryTypeError> {
280        self.as_array().ok_or(TryTypeError {
281            expected: ValueType::Array,
282            got: self.value_type(),
283        })
284    }
285
286    /// Tries to represent the value as an object and returns a reference to it
287    /// # Errors
288    /// if the requested type doesn't match the actual type
289    pub fn try_as_object(&self) -> Result<Object<'_, 'tape, 'input>, TryTypeError> {
290        self.as_object().ok_or(TryTypeError {
291            expected: ValueType::Object,
292            got: self.value_type(),
293        })
294    }
295}
296// ValueObjectAccess (needed as we don't have ValueAsContainer ) and can't return references
297impl<'tape, 'input> Value<'_, 'tape, 'input> {
298    /// Gets a ref to a value based on a key, returns `None` if the
299    /// current Value isn't an Object or doesn't contain the key
300    /// it was asked for.
301    #[must_use]
302    pub fn get<'k, Q>(&self, k: &'k Q) -> Option<Value<'_, 'tape, 'input>>
303    where
304        str: Borrow<Q>,
305        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
306        Q: ?Sized + Hash + Eq + Ord,
307    {
308        match self {
309            Value::Tape(tape) => tape.get(k).map(Value::Tape),
310            Value::Value(value) => value
311                .as_object()?
312                .get(k)
313                .map(Cow::Borrowed)
314                .map(Value::Value),
315        }
316    }
317
318    /// Checks if a Value contains a given key. This will return
319    /// flase if Value isn't an object  
320    #[must_use]
321    pub fn contains_key<Q>(&self, k: &Q) -> bool
322    where
323        str: Borrow<Q>,
324        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
325        Q: ?Sized + Hash + Eq + Ord,
326    {
327        let Some(o) = self.as_object() else {
328            return false;
329        };
330
331        o.get(k).is_some()
332    }
333}
334
335// ValueArrayAccess (needed as we don't have ValueAsContainer)
336impl<'tape, 'input> Value<'_, 'tape, 'input> {
337    /// Gets a ref to a value based on n index, returns `None` if the
338    /// current Value isn't an Array or doesn't contain the index
339    /// it was asked for.
340    #[must_use]
341    pub fn get_idx(&self, i: usize) -> Option<Value<'_, 'tape, 'input>> {
342        match self {
343            Value::Tape(tape) => tape.get_idx(i).map(Value::Tape),
344            Value::Value(value) => value
345                .as_array()?
346                .get(i)
347                .map(Cow::Borrowed)
348                .map(Value::Value),
349        }
350    }
351}
352
353// impl<'tape, 'input> ValueObjectAccessAsScalar for Value<'tape, 'input>
354impl<'tape, 'input> Value<'_, 'tape, 'input>
355where
356    'input: 'tape,
357{
358    /// Tries to get an element of an object as a bool
359    pub fn get_bool<Q>(&self, k: &Q) -> Option<bool>
360    where
361        str: Borrow<Q>,
362        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
363        Q: ?Sized + Hash + Eq + Ord,
364    {
365        self.get(k)?.as_bool()
366    }
367
368    /// Tries to get an element of an object as a i128
369    #[cfg_attr(not(feature = "no-inline"), inline)]
370    pub fn get_i128<Q>(&self, k: &Q) -> Option<i128>
371    where
372        str: Borrow<Q>,
373        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
374        Q: ?Sized + Hash + Eq + Ord,
375    {
376        self.get(k)?.as_i128()
377    }
378
379    /// Tries to get an element of an object as a i64
380    #[cfg_attr(not(feature = "no-inline"), inline)]
381    pub fn get_i64<Q>(&self, k: &Q) -> Option<i64>
382    where
383        str: Borrow<Q>,
384        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
385        Q: ?Sized + Hash + Eq + Ord,
386    {
387        self.get(k)?.as_i64()
388    }
389
390    /// Tries to get an element of an object as a i32
391    #[cfg_attr(not(feature = "no-inline"), inline)]
392    pub fn get_i32<Q>(&self, k: &Q) -> Option<i32>
393    where
394        str: Borrow<Q>,
395        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
396        Q: ?Sized + Hash + Eq + Ord,
397    {
398        self.get(k)?.as_i32()
399    }
400
401    /// Tries to get an element of an object as a i16
402    #[cfg_attr(not(feature = "no-inline"), inline)]
403    pub fn get_i16<Q>(&self, k: &Q) -> Option<i16>
404    where
405        str: Borrow<Q>,
406        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
407        Q: ?Sized + Hash + Eq + Ord,
408    {
409        self.get(k)?.as_i16()
410    }
411
412    /// Tries to get an element of an object as a i8
413    #[cfg_attr(not(feature = "no-inline"), inline)]
414    pub fn get_i8<Q>(&self, k: &Q) -> Option<i8>
415    where
416        str: Borrow<Q>,
417        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
418        Q: ?Sized + Hash + Eq + Ord,
419    {
420        self.get(k)?.as_i8()
421    }
422
423    /// Tries to get an element of an object as a u128
424    #[cfg_attr(not(feature = "no-inline"), inline)]
425    pub fn get_u128<Q>(&self, k: &Q) -> Option<u128>
426    where
427        str: Borrow<Q>,
428        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
429        Q: ?Sized + Hash + Eq + Ord,
430    {
431        self.get(k)?.as_u128()
432    }
433
434    /// Tries to get an element of an object as a u64
435    #[cfg_attr(not(feature = "no-inline"), inline)]
436    pub fn get_u64<Q>(&self, k: &Q) -> Option<u64>
437    where
438        str: Borrow<Q>,
439        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
440        Q: ?Sized + Hash + Eq + Ord,
441    {
442        self.get(k).and_then(|v| v.as_u64())
443    }
444
445    /// Tries to get an element of an object as a usize
446    #[cfg_attr(not(feature = "no-inline"), inline)]
447    pub fn get_usize<Q>(&self, k: &Q) -> Option<usize>
448    where
449        str: Borrow<Q>,
450        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
451        Q: ?Sized + Hash + Eq + Ord,
452    {
453        self.get(k).and_then(|v| v.as_usize())
454    }
455
456    /// Tries to get an element of an object as a u32
457    #[cfg_attr(not(feature = "no-inline"), inline)]
458    pub fn get_u32<Q>(&self, k: &Q) -> Option<u32>
459    where
460        str: Borrow<Q>,
461        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
462        Q: ?Sized + Hash + Eq + Ord,
463    {
464        self.get(k).and_then(|v| v.as_u32())
465    }
466
467    /// Tries to get an element of an object as a u16
468    #[cfg_attr(not(feature = "no-inline"), inline)]
469    pub fn get_u16<Q>(&self, k: &Q) -> Option<u16>
470    where
471        str: Borrow<Q>,
472        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
473        Q: ?Sized + Hash + Eq + Ord,
474    {
475        self.get(k).and_then(|v| v.as_u16())
476    }
477
478    /// Tries to get an element of an object as a u8
479    #[cfg_attr(not(feature = "no-inline"), inline)]
480    pub fn get_u8<Q>(&self, k: &Q) -> Option<u8>
481    where
482        str: Borrow<Q>,
483        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
484        Q: ?Sized + Hash + Eq + Ord,
485    {
486        self.get(k).and_then(|v| v.as_u8())
487    }
488
489    /// Tries to get an element of an object as a f64
490    #[cfg_attr(not(feature = "no-inline"), inline)]
491    pub fn get_f64<Q>(&self, k: &Q) -> Option<f64>
492    where
493        str: Borrow<Q>,
494        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
495        Q: ?Sized + Hash + Eq + Ord,
496    {
497        self.get(k).and_then(|v| v.as_f64())
498    }
499
500    /// Tries to get an element of an object as a f32
501    #[cfg_attr(not(feature = "no-inline"), inline)]
502    pub fn get_f32<Q>(&self, k: &Q) -> Option<f32>
503    where
504        str: Borrow<Q>,
505        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
506        Q: ?Sized + Hash + Eq + Ord,
507    {
508        self.get(k).and_then(|v| v.as_f32())
509    }
510    /// Tries to get an element of an object as a str
511    #[cfg_attr(not(feature = "no-inline"), inline)]
512    pub fn get_str<Q>(&self, k: &Q) -> Option<&str>
513    where
514        str: Borrow<Q>,
515        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
516        Q: ?Sized + Hash + Eq + Ord,
517    {
518        match self {
519            Value::Tape(tape) => tape.get_str(k),
520            Value::Value(value) => value.get_str(k),
521        }
522    }
523}
524
525// ValueObjectContainerAccess
526impl<'tape, 'input> Value<'_, 'tape, 'input> {
527    /// Tries to get an element of an object as a array
528    #[must_use]
529    pub fn get_array<Q>(&self, k: &Q) -> Option<Array<'_, 'tape, 'input>>
530    where
531        str: Borrow<Q>,
532        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
533        Q: ?Sized + Hash + Eq + Ord,
534    {
535        match self {
536            Value::Tape(tape) => tape.get_array(k).map(Array::Tape),
537            Value::Value(value) => value.get_array(k).map(Array::Value),
538        }
539    }
540
541    /// Tries to get an element of an object as a object
542    #[must_use]
543    pub fn get_object<Q>(&self, k: &Q) -> Option<Object<'_, 'tape, 'input>>
544    where
545        str: Borrow<Q>,
546        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
547        Q: ?Sized + Hash + Eq + Ord,
548    {
549        match self {
550            Value::Tape(tape) => tape.get_object(k).map(Object::Tape),
551            Value::Value(value) => value.get_object(k).map(Object::Value),
552        }
553    }
554}
555// TryValueObjectContainerAccess
556impl<'tape, 'input> Value<'_, 'tape, 'input> {
557    /// Tries to get an element of an object as an array, returns
558    /// an error if it isn't a array
559    /// # Errors
560    /// if the requested type doesn't match the actual type or the value is not an object
561    pub fn try_get_array<Q>(&self, k: &Q) -> Result<Option<Array<'_, 'tape, 'input>>, TryTypeError>
562    where
563        str: Borrow<Q>,
564        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
565        Q: ?Sized + Hash + Eq + Ord,
566    {
567        match self {
568            Value::Tape(tape) => Ok(tape.try_get_array(k)?.map(Array::Tape)),
569            Value::Value(value) => Ok(value.try_get_array(k)?.map(Array::Value)),
570        }
571    }
572
573    /// Tries to get an element of an object as an object, returns
574    /// an error if it isn't an object
575    ///
576    /// # Errors
577    /// if the requested type doesn't match the actual type or the value is not an object
578    pub fn try_get_object<Q>(
579        &self,
580        k: &Q,
581    ) -> Result<Option<Object<'_, 'tape, 'input>>, TryTypeError>
582    where
583        str: Borrow<Q>,
584        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
585        Q: ?Sized + Hash + Eq + Ord,
586    {
587        match self {
588            Value::Tape(tape) => Ok(tape.try_get_object(k)?.map(Object::Tape)),
589            Value::Value(value) => Ok(value.try_get_object(k)?.map(Object::Value)),
590        }
591    }
592}
593
594// impl<'tape, 'input> ValueObjectAccessTryAsScalar for Value<'tape, 'input> {
595impl Value<'_, '_, '_> {
596    /// Tries to get an element of an object as a bool, returns
597    /// an error if it isn't bool
598    /// # Errors
599    /// if the requested type doesn't match the actual type or the value is not an object
600    pub fn try_get_bool<Q>(&self, k: &Q) -> Result<Option<bool>, TryTypeError>
601    where
602        str: Borrow<Q>,
603        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
604        Q: ?Sized + Hash + Eq + Ord,
605    {
606        self.try_get(k)?.map(|v| v.try_as_bool()).transpose()
607    }
608
609    /// Tries to get an element of an object as a i128, returns
610    /// an error if it isn't i128
611    /// # Errors
612    /// if the requested type doesn't match the actual type or the value is not an object
613    #[cfg_attr(not(feature = "no-inline"), inline)]
614    pub fn try_get_i128<Q>(&self, k: &Q) -> Result<Option<i128>, TryTypeError>
615    where
616        str: Borrow<Q>,
617        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
618        Q: ?Sized + Hash + Eq + Ord,
619    {
620        self.try_get(k)?.map(|v| v.try_as_i128()).transpose()
621    }
622
623    /// Tries to get an element of an object as a i64, returns
624    /// an error if it isn't a i64
625    /// # Errors
626    /// if the requested type doesn't match the actual type or the value is not an object
627    #[cfg_attr(not(feature = "no-inline"), inline)]
628    pub fn try_get_i64<Q>(&self, k: &Q) -> Result<Option<i64>, TryTypeError>
629    where
630        str: Borrow<Q>,
631        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
632        Q: ?Sized + Hash + Eq + Ord,
633    {
634        self.try_get(k)?.map(|v| v.try_as_i64()).transpose()
635    }
636
637    /// Tries to get an element of an object as a i32, returns
638    /// an error if it isn't a i32
639    /// # Errors
640    /// if the requested type doesn't match the actual type or the value is not an object
641    #[cfg_attr(not(feature = "no-inline"), inline)]
642    pub fn try_get_i32<Q>(&self, k: &Q) -> Result<Option<i32>, TryTypeError>
643    where
644        str: Borrow<Q>,
645        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
646        Q: ?Sized + Hash + Eq + Ord,
647    {
648        self.try_get(k)?.map(|v| v.try_as_i32()).transpose()
649    }
650
651    /// Tries to get an element of an object as a i16, returns
652    /// an error if it isn't a i16
653    /// # Errors
654    /// if the requested type doesn't match the actual type or the value is not an object
655    #[cfg_attr(not(feature = "no-inline"), inline)]
656    pub fn try_get_i16<Q>(&self, k: &Q) -> Result<Option<i16>, TryTypeError>
657    where
658        str: Borrow<Q>,
659        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
660        Q: ?Sized + Hash + Eq + Ord,
661    {
662        self.try_get(k)?.map(|v| v.try_as_i16()).transpose()
663    }
664
665    /// Tries to get an element of an object as a u128, returns
666    /// an error if it isn't a u128
667    /// # Errors
668    /// if the requested type doesn't match the actual type or the value is not an object
669    #[cfg_attr(not(feature = "no-inline"), inline)]
670    pub fn try_get_i8<Q>(&self, k: &Q) -> Result<Option<i8>, TryTypeError>
671    where
672        str: Borrow<Q>,
673        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
674        Q: ?Sized + Hash + Eq + Ord,
675    {
676        self.try_get(k)?.map(|v| v.try_as_i8()).transpose()
677    }
678
679    /// Tries to get an element of an object as a u64, returns
680    /// an error if it isn't a u64
681    /// # Errors
682    /// if the requested type doesn't match the actual type or the value is not an object
683    #[cfg_attr(not(feature = "no-inline"), inline)]
684    pub fn try_get_u128<Q>(&self, k: &Q) -> Result<Option<u128>, TryTypeError>
685    where
686        str: Borrow<Q>,
687        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
688        Q: ?Sized + Hash + Eq + Ord,
689    {
690        self.try_get(k)?.map(|v| v.try_as_u128()).transpose()
691    }
692
693    /// Tries to get an element of an object as a usize, returns
694    /// an error if it isn't a usize
695    /// # Errors
696    /// if the requested type doesn't match the actual type or the value is not an object
697    #[cfg_attr(not(feature = "no-inline"), inline)]
698    pub fn try_get_u64<Q>(&self, k: &Q) -> Result<Option<u64>, TryTypeError>
699    where
700        str: Borrow<Q>,
701        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
702        Q: ?Sized + Hash + Eq + Ord,
703    {
704        self.try_get(k)?.map(|v| v.try_as_u64()).transpose()
705    }
706
707    /// Tries to get an element of an object as a u32, returns
708    /// an error if it isn't a u32
709    /// # Errors
710    /// if the requested type doesn't match the actual type or the value is not an object
711    #[cfg_attr(not(feature = "no-inline"), inline)]
712    pub fn try_get_usize<Q>(&self, k: &Q) -> Result<Option<usize>, TryTypeError>
713    where
714        str: Borrow<Q>,
715        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
716        Q: ?Sized + Hash + Eq + Ord,
717    {
718        self.try_get(k)?.map(|v| v.try_as_usize()).transpose()
719    }
720
721    /// Tries to get an element of an object as a u16, returns
722    /// an error if it isn't a u16
723    /// # Errors
724    /// if the requested type doesn't match the actual type or the value is not an object
725    #[cfg_attr(not(feature = "no-inline"), inline)]
726    pub fn try_get_u32<Q>(&self, k: &Q) -> Result<Option<u32>, TryTypeError>
727    where
728        str: Borrow<Q>,
729        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
730        Q: ?Sized + Hash + Eq + Ord,
731    {
732        self.try_get(k)?.map(|v| v.try_as_u32()).transpose()
733    }
734
735    /// Tries to get an element of an object as a u8, returns
736    /// an error if it isn't a u8
737    /// # Errors
738    /// if the requested type doesn't match the actual type or the value is not an object
739    #[cfg_attr(not(feature = "no-inline"), inline)]
740    pub fn try_get_u16<Q>(&self, k: &Q) -> Result<Option<u16>, TryTypeError>
741    where
742        str: Borrow<Q>,
743        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
744        Q: ?Sized + Hash + Eq + Ord,
745    {
746        self.try_get(k)?.map(|v| v.try_as_u16()).transpose()
747    }
748
749    /// Tries to get an element of an object as a u8, returns
750    /// an error if it isn't a u8
751    /// # Errors
752    /// if the requested type doesn't match the actual type or the value is not an object
753    #[cfg_attr(not(feature = "no-inline"), inline)]
754    pub fn try_get_u8<Q>(&self, k: &Q) -> Result<Option<u8>, TryTypeError>
755    where
756        str: Borrow<Q>,
757        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
758        Q: ?Sized + Hash + Eq + Ord,
759    {
760        self.try_get(k)?.map(|v| v.try_as_u8()).transpose()
761    }
762
763    /// Tries to get an element of an object as a f64, returns
764    /// an error if it isn't a f64
765    /// # Errors
766    /// if the requested type doesn't match the actual type or the value is not an object
767    #[cfg_attr(not(feature = "no-inline"), inline)]
768    pub fn try_get_f64<Q>(&self, k: &Q) -> Result<Option<f64>, TryTypeError>
769    where
770        str: Borrow<Q>,
771        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
772        Q: ?Sized + Hash + Eq + Ord,
773    {
774        self.try_get(k)?.map(|v| v.try_as_f64()).transpose()
775    }
776
777    /// Tries to get an element of an object as a f32, returns
778    /// an error if it isn't a f32
779    /// # Errors
780    /// if the requested type doesn't match the actual type or the value is not an object
781    #[cfg_attr(not(feature = "no-inline"), inline)]
782    pub fn try_get_f32<Q>(&self, k: &Q) -> Result<Option<f32>, TryTypeError>
783    where
784        str: Borrow<Q>,
785        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
786        Q: ?Sized + Hash + Eq + Ord,
787    {
788        self.try_get(k)?.map(|v| v.try_as_f32()).transpose()
789    }
790
791    /// Tries to get an element of an object as a str, returns
792    /// an error if it isn't a str
793    /// # Errors
794    /// if the requested type doesn't match the actual type or the value is not an object
795    #[cfg_attr(not(feature = "no-inline"), inline)]
796    pub fn try_get_str<Q>(&self, k: &Q) -> Result<Option<&'_ str>, TryTypeError>
797    where
798        str: Borrow<Q>,
799        for<'a> crate::cow::Cow<'a, str>: Borrow<Q>,
800        Q: ?Sized + Hash + Eq + Ord,
801    {
802        match self {
803            Value::Tape(tape) => tape.try_get_str(k),
804            Value::Value(value) => value.try_get_str(k),
805        }
806    }
807}
808
809impl Writable for Value<'_, '_, '_> {
810    #[cfg_attr(not(feature = "no-inline"), inline)]
811    fn encode(&self) -> String {
812        match self {
813            Value::Tape(tape) => tape.encode(),
814            Value::Value(value) => value.encode(),
815        }
816    }
817
818    #[cfg_attr(not(feature = "no-inline"), inline)]
819    fn encode_pp(&self) -> String {
820        match self {
821            Value::Tape(tape) => tape.encode_pp(),
822            Value::Value(value) => value.encode_pp(),
823        }
824    }
825
826    #[cfg_attr(not(feature = "no-inline"), inline)]
827    fn write<'writer, W>(&self, w: &mut W) -> io::Result<()>
828    where
829        W: 'writer + Write,
830    {
831        match self {
832            Value::Tape(tape) => tape.write(w),
833            Value::Value(value) => value.write(w),
834        }
835    }
836
837    #[cfg_attr(not(feature = "no-inline"), inline)]
838    fn write_pp<'writer, W>(&self, w: &mut W) -> io::Result<()>
839    where
840        W: 'writer + Write,
841    {
842        match self {
843            Value::Tape(tape) => tape.write_pp(w),
844            Value::Value(value) => value.write_pp(w),
845        }
846    }
847}