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