Skip to main content

platform_value/
lib.rs

1//! Platform value
2//! A dynamic Platform value
3//!
4//! A module that is used to represent values in Platform components
5//! Forked from ciborium value
6//!
7//!
8extern crate core;
9
10pub mod btreemap_extensions;
11pub mod converter;
12pub mod display;
13mod eq;
14mod error;
15mod index;
16mod inner_array_value;
17pub mod inner_value;
18mod inner_value_at_path;
19mod macros;
20pub mod patch;
21mod pointer;
22mod replace;
23pub mod string_encoding;
24pub mod system_bytes;
25mod types;
26mod value_map;
27mod value_serialization;
28
29pub use crate::value_map::{ValueMap, ValueMapHelper};
30pub use error::Error;
31use std::collections::BTreeMap;
32
33pub type Hash256 = [u8; 32];
34
35pub use btreemap_extensions::btreemap_field_replacement::{
36    IntegerReplacementType, ReplacementType,
37};
38pub use types::binary_data::BinaryData;
39pub use types::bytes_20::Bytes20;
40pub use types::bytes_32::Bytes32;
41pub use types::bytes_36::Bytes36;
42pub use types::identifier::{Identifier, IdentifierBytes32, IDENTIFIER_MEDIA_TYPE};
43
44pub use value_serialization::{from_value, to_value};
45
46use bincode::de::Decoder;
47use bincode::error::{AllowedEnumVariants, DecodeError};
48use bincode::{Decode, Encode};
49pub use patch::{patch, Patch};
50
51/// The defensive nesting limit used when decoding a [`Value`] without an explicit scope.
52pub const DEFAULT_MAX_VALUE_DECODE_DEPTH: usize = 256;
53
54std::thread_local! {
55    static VALUE_DECODE_DEPTH_LIMIT: std::cell::Cell<Option<usize>> =
56        const { std::cell::Cell::new(Some(DEFAULT_MAX_VALUE_DECODE_DEPTH)) };
57}
58
59/// Runs `decode` with the requested container-depth limit for [`Value`] decoding on this thread.
60///
61/// This is used by version-aware protocol decoders so historical versions can retain their
62/// original behavior while current versions reject excessive nesting before constructing a
63/// recursive value tree.
64pub fn with_value_decode_depth_limit<T>(max_depth: Option<usize>, decode: impl FnOnce() -> T) -> T {
65    struct RestoreDepthLimit(Option<usize>);
66
67    impl Drop for RestoreDepthLimit {
68        fn drop(&mut self) {
69            VALUE_DECODE_DEPTH_LIMIT.with(|limit| limit.set(self.0));
70        }
71    }
72
73    let previous_limit = VALUE_DECODE_DEPTH_LIMIT.with(|limit| limit.replace(max_depth));
74    let _restore_limit = RestoreDepthLimit(previous_limit);
75    decode()
76}
77
78/// A representation of a dynamic value that can handled dynamically
79#[non_exhaustive]
80#[derive(Clone, Debug, PartialEq, PartialOrd, Encode)]
81pub enum Value {
82    /// A u128 integer
83    U128(u128),
84
85    /// A i128 integer
86    I128(i128),
87
88    /// A u64 integer
89    U64(u64),
90
91    /// A i64 integer
92    I64(i64),
93
94    /// A u32 integer
95    U32(u32),
96
97    /// A i32 integer
98    I32(i32),
99
100    /// A u16 integer
101    U16(u16),
102
103    /// A i16 integer
104    I16(i16),
105
106    /// A u8 integer
107    U8(u8),
108
109    /// A i8 integer
110    I8(i8),
111
112    /// Bytes
113    Bytes(Vec<u8>),
114
115    /// Bytes 20
116    Bytes20([u8; 20]),
117
118    /// Bytes 32
119    Bytes32([u8; 32]),
120
121    /// Bytes 36 : Useful for outpoints
122    Bytes36([u8; 36]),
123
124    /// An enumeration of u8
125    EnumU8(Vec<u8>),
126
127    /// An enumeration of strings
128    EnumString(Vec<String>),
129
130    /// Identifier
131    /// The identifier is very similar to bytes, however it is serialized to Base58 when converted
132    /// to a JSON Value
133    Identifier(Hash256),
134
135    /// A float
136    Float(f64),
137
138    /// A string
139    Text(String),
140
141    /// A boolean
142    Bool(bool),
143
144    /// Null
145    Null,
146
147    /// An array
148    Array(Vec<Value>),
149
150    /// A map
151    Map(ValueMap),
152}
153
154enum ValueDecodeFrame {
155    Array {
156        values: Vec<Value>,
157        remaining: usize,
158    },
159    Map {
160        entries: ValueMap,
161        remaining: usize,
162        pending_key: Option<Value>,
163    },
164}
165
166fn decode_value_container_len<Context, D>(decoder: &mut D) -> Result<usize, DecodeError>
167where
168    D: Decoder<Context = Context>,
169{
170    let len = <u64 as Decode<Context>>::decode(decoder)?;
171    len.try_into()
172        .map_err(|_| DecodeError::OutsideUsizeRange(len))
173}
174
175fn validate_value_decode_depth(depth: usize) -> Result<(), DecodeError> {
176    VALUE_DECODE_DEPTH_LIMIT.with(|limit| match limit.get() {
177        Some(max_depth) if depth > max_depth => Err(DecodeError::OtherString(format!(
178            "value nesting depth {depth} exceeds maximum {max_depth}"
179        ))),
180        _ => Ok(()),
181    })
182}
183
184impl<Context> Decode<Context> for Value {
185    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
186        let mut frames = Vec::<ValueDecodeFrame>::new();
187        let mut completed_value = None;
188
189        loop {
190            if let Some(value) = completed_value.take() {
191                let Some(frame) = frames.last_mut() else {
192                    return Ok(value);
193                };
194
195                match frame {
196                    ValueDecodeFrame::Array { values, remaining } => {
197                        values.push(value);
198                        *remaining -= 1;
199
200                        if *remaining == 0 {
201                            let ValueDecodeFrame::Array { values, .. } =
202                                frames.pop().expect("the array frame was just observed")
203                            else {
204                                unreachable!("the observed frame changed")
205                            };
206                            completed_value = Some(Value::Array(values));
207                        } else {
208                            decoder.unclaim_bytes_read(std::mem::size_of::<Value>());
209                        }
210                    }
211                    ValueDecodeFrame::Map {
212                        entries,
213                        remaining,
214                        pending_key,
215                    } => {
216                        if pending_key.is_none() {
217                            *pending_key = Some(value);
218                        } else {
219                            let key = pending_key
220                                .take()
221                                .expect("the map frame was expecting a value");
222                            entries.push((key, value));
223                            *remaining -= 1;
224
225                            if *remaining == 0 {
226                                let ValueDecodeFrame::Map { entries, .. } =
227                                    frames.pop().expect("the map frame was just observed")
228                                else {
229                                    unreachable!("the observed frame changed")
230                                };
231                                completed_value = Some(Value::Map(entries));
232                            } else {
233                                decoder.unclaim_bytes_read(std::mem::size_of::<(Value, Value)>());
234                            }
235                        }
236                    }
237                }
238
239                continue;
240            }
241
242            let variant_index = <u32 as Decode<Context>>::decode(decoder)?;
243            completed_value = Some(match variant_index {
244                0 => Value::U128(Decode::decode(decoder)?),
245                1 => Value::I128(Decode::decode(decoder)?),
246                2 => Value::U64(Decode::decode(decoder)?),
247                3 => Value::I64(Decode::decode(decoder)?),
248                4 => Value::U32(Decode::decode(decoder)?),
249                5 => Value::I32(Decode::decode(decoder)?),
250                6 => Value::U16(Decode::decode(decoder)?),
251                7 => Value::I16(Decode::decode(decoder)?),
252                8 => Value::U8(Decode::decode(decoder)?),
253                9 => Value::I8(Decode::decode(decoder)?),
254                10 => Value::Bytes(Decode::decode(decoder)?),
255                11 => Value::Bytes20(Decode::decode(decoder)?),
256                12 => Value::Bytes32(Decode::decode(decoder)?),
257                13 => Value::Bytes36(Decode::decode(decoder)?),
258                14 => Value::EnumU8(Decode::decode(decoder)?),
259                15 => Value::EnumString(Decode::decode(decoder)?),
260                16 => Value::Identifier(Decode::decode(decoder)?),
261                17 => Value::Float(Decode::decode(decoder)?),
262                18 => Value::Text(Decode::decode(decoder)?),
263                19 => Value::Bool(Decode::decode(decoder)?),
264                20 => Value::Null,
265                21 => {
266                    validate_value_decode_depth(frames.len() + 1)?;
267                    let len = decode_value_container_len(decoder)?;
268                    decoder.claim_container_read::<Value>(len)?;
269
270                    if len == 0 {
271                        Value::Array(Vec::new())
272                    } else {
273                        frames.push(ValueDecodeFrame::Array {
274                            values: Vec::with_capacity(len),
275                            remaining: len,
276                        });
277                        decoder.unclaim_bytes_read(std::mem::size_of::<Value>());
278                        continue;
279                    }
280                }
281                22 => {
282                    validate_value_decode_depth(frames.len() + 1)?;
283                    let len = decode_value_container_len(decoder)?;
284                    decoder.claim_container_read::<(Value, Value)>(len)?;
285
286                    if len == 0 {
287                        Value::Map(Vec::new())
288                    } else {
289                        frames.push(ValueDecodeFrame::Map {
290                            entries: Vec::with_capacity(len),
291                            remaining: len,
292                            pending_key: None,
293                        });
294                        decoder.unclaim_bytes_read(std::mem::size_of::<(Value, Value)>());
295                        continue;
296                    }
297                }
298                found => {
299                    return Err(DecodeError::UnexpectedVariant {
300                        type_name: std::any::type_name::<Self>(),
301                        allowed: &AllowedEnumVariants::Range { min: 0, max: 22 },
302                        found,
303                    });
304                }
305            });
306        }
307    }
308}
309
310bincode::impl_borrow_decode!(Value);
311
312impl Value {
313    /// Returns true if the `Value` is an `Integer`. Returns false otherwise.
314    ///
315    /// ```
316    /// # use platform_value::Value;
317    /// #
318    /// let value = Value::U64(17);
319    ///
320    /// assert!(value.is_integer());
321    /// ```
322    pub fn is_integer(&self) -> bool {
323        matches!(
324            self,
325            Value::U128(_)
326                | Value::I128(_)
327                | Value::U64(_)
328                | Value::I64(_)
329                | Value::U32(_)
330                | Value::I32(_)
331                | Value::U16(_)
332                | Value::I16(_)
333                | Value::U8(_)
334                | Value::I8(_)
335        )
336    }
337
338    /// Returns true if the `Value` is an integer that fits in 64 bits (u64/i64).
339    /// Returns false otherwise.
340    ///
341    /// ```
342    /// # use platform_value::Value;
343    /// #
344    /// let value = Value::U128(17);
345    ///
346    /// assert!(value.is_integer_can_fit_in_64_bits());
347    /// ```
348    pub fn is_integer_can_fit_in_64_bits(&self) -> bool {
349        match self {
350            // Already ≤ 64-bit widths
351            Value::U64(_)
352            | Value::I64(_)
353            | Value::U32(_)
354            | Value::I32(_)
355            | Value::U16(_)
356            | Value::I16(_)
357            | Value::U8(_)
358            | Value::I8(_) => true,
359
360            // 128-bit -> check if within 64-bit range
361            Value::U128(v) => *v <= u64::MAX as u128,
362            Value::I128(v) => (*v >= i64::MIN as i128) && (*v <= i64::MAX as i128),
363
364            // Non-integer variants
365            _ => false,
366        }
367    }
368
369    /// If the `Value` is a `Integer`, returns a reference to the associated `Integer` data.
370    /// Returns None otherwise.
371    ///
372    /// ```
373    /// # use platform_value::Value;
374    /// #
375    /// let value = Value::U64(17);
376    ///
377    /// // We can read the number
378    /// let r_value : u64 = value.as_integer().unwrap();
379    /// assert_eq!(17, r_value);
380    /// ```
381    pub fn as_integer<T>(&self) -> Option<T>
382    where
383        T: TryFrom<i128>
384            + TryFrom<u128>
385            + TryFrom<u64>
386            + TryFrom<i64>
387            + TryFrom<u32>
388            + TryFrom<i32>
389            + TryFrom<u16>
390            + TryFrom<i16>
391            + TryFrom<u8>
392            + TryFrom<i8>,
393    {
394        match self {
395            Value::U128(int) => (*int).try_into().ok(),
396            Value::I128(int) => (*int).try_into().ok(),
397            Value::U64(int) => (*int).try_into().ok(),
398            Value::I64(int) => (*int).try_into().ok(),
399            Value::U32(int) => (*int).try_into().ok(),
400            Value::I32(int) => (*int).try_into().ok(),
401            Value::U16(int) => (*int).try_into().ok(),
402            Value::I16(int) => (*int).try_into().ok(),
403            Value::U8(int) => (*int).try_into().ok(),
404            Value::I8(int) => (*int).try_into().ok(),
405            _ => None,
406        }
407    }
408
409    /// If the `Value` is a `Integer`, returns a the associated `Integer` data as `Ok`.
410    /// Returns `Err(Error::Structure("reason"))` otherwise.
411    ///
412    /// ```
413    /// # use platform_value::{Value, Error};
414    /// #
415    /// let value = Value::U64(17);
416    /// let r_value : Result<u64,Error> = value.into_integer();
417    /// assert_eq!(r_value, Ok(17));
418    ///
419    /// let value = Value::Bool(true);
420    /// let r_value : Result<u64,Error> = value.into_integer();
421    /// assert_eq!(r_value, Err(Error::StructureError("value is not an integer".to_string())));
422    /// ```
423    pub fn into_integer<T>(self) -> Result<T, Error>
424    where
425        T: TryFrom<i128>
426            + TryFrom<u128>
427            + TryFrom<u64>
428            + TryFrom<i64>
429            + TryFrom<u32>
430            + TryFrom<i32>
431            + TryFrom<u16>
432            + TryFrom<i16>
433            + TryFrom<u8>
434            + TryFrom<i8>,
435    {
436        match self {
437            Value::U128(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
438            Value::I128(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
439            Value::U64(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
440            Value::I64(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
441            Value::U32(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
442            Value::I32(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
443            Value::U16(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
444            Value::I16(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
445            Value::U8(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
446            Value::I8(int) => int.try_into().map_err(|_| Error::IntegerSizeError),
447            _other => Err(Error::StructureError("value is not an integer".to_string())),
448        }
449    }
450
451    /// If the `Value` is a `Integer`, returns a the associated `Integer` data as `Ok`.
452    /// Returns `Err(Error::Structure("reason"))` otherwise.
453    ///
454    /// ```
455    /// # use platform_value::{Value, Error};
456    /// #
457    /// let value = Value::U64(17);
458    /// let r_value : Result<u64,Error> = value.to_integer();
459    /// assert_eq!(r_value, Ok(17));
460    ///
461    /// let value = Value::Bool(true);
462    /// let r_value : Result<u64,Error> = value.to_integer();
463    /// assert_eq!(r_value, Err(Error::StructureError("value is not an integer, found bool true".to_string())));
464    /// ```
465    pub fn to_integer<T>(&self) -> Result<T, Error>
466    where
467        T: TryFrom<i128>
468            + TryFrom<u128>
469            + TryFrom<u64>
470            + TryFrom<i64>
471            + TryFrom<u32>
472            + TryFrom<i32>
473            + TryFrom<u16>
474            + TryFrom<i16>
475            + TryFrom<u8>
476            + TryFrom<i8>,
477    {
478        match self {
479            Value::U128(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
480            Value::I128(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
481            Value::U64(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
482            Value::I64(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
483            Value::U32(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
484            Value::I32(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
485            Value::U16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
486            Value::I16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
487            Value::U8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
488            Value::I8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
489            other => Err(Error::StructureError(format!(
490                "value is not an integer, found {}",
491                other
492            ))),
493        }
494    }
495
496    /// If the `Value` is an `Integer`, a `String` or a `Float` or even a `Bool`, returns the
497    /// associated `Integer` data as `Ok`.
498    /// Returns `Err(Error::Structure("reason"))` otherwise.
499    ///
500    /// ```
501    /// # use platform_value::{Value, Error};
502    /// #
503    /// let value = Value::U64(17);
504    /// let r_value : Result<u64,Error> = value.to_integer_broad_conversion();
505    /// assert_eq!(r_value, Ok(17));
506    ///
507    /// let value = Value::Text("17".to_string());
508    /// let r_value : Result<u64,Error> = value.to_integer_broad_conversion();
509    /// assert_eq!(r_value, Ok(17));
510    ///
511    /// let value = Value::Bool(true);
512    /// let r_value : Result<u64,Error> = value.to_integer_broad_conversion();
513    /// assert_eq!(r_value, Ok(1));
514    /// ```
515    pub fn to_integer_broad_conversion<T>(&self) -> Result<T, Error>
516    where
517        T: TryFrom<i128>
518            + TryFrom<u128>
519            + TryFrom<u64>
520            + TryFrom<i64>
521            + TryFrom<u32>
522            + TryFrom<i32>
523            + TryFrom<u16>
524            + TryFrom<i16>
525            + TryFrom<u8>
526            + TryFrom<i8>,
527    {
528        match self {
529            Value::U128(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
530            Value::I128(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
531            Value::U64(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
532            Value::I64(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
533            Value::U32(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
534            Value::I32(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
535            Value::U16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
536            Value::I16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
537            Value::U8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
538            Value::I8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError),
539            Value::Float(float) => {
540                let max_f64 = u128::MAX as f64;
541                let min_f64 = i128::MIN as f64;
542                if *float > 0f64 && *float < max_f64 {
543                    (*float as u128)
544                        .try_into()
545                        .map_err(|_| Error::IntegerSizeError)
546                } else if *float > min_f64 && *float < 0f64 {
547                    (*float as i128)
548                        .try_into()
549                        .map_err(|_| Error::IntegerSizeError)
550                } else {
551                    Err(Error::IntegerSizeError)
552                }
553            }
554            Value::Bool(bool) => {
555                let i: u8 = (*bool).into();
556                i.try_into().map_err(|_| Error::IntegerSizeError)
557            }
558            Value::Text(text) => text
559                .parse::<i128>()
560                .map_err(|_| Error::IntegerSizeError)?
561                .try_into()
562                .map_err(|_| Error::IntegerSizeError),
563            other => Err(Error::StructureError(format!(
564                "value can not be converted to an integer, found {}",
565                other
566            ))),
567        }
568    }
569
570    /// Returns true if the `Value` is a `Bytes`. Returns false otherwise.
571    ///
572    /// ```
573    /// # use platform_value::Value;
574    /// #
575    /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]);
576    ///
577    /// assert!(value.is_bytes());
578    /// ```
579    pub fn is_bytes(&self) -> bool {
580        self.as_bytes().is_some()
581    }
582
583    /// Returns true if the `Value` is a `Bytes`. Returns false otherwise.
584    ///
585    /// ```
586    /// # use platform_value::Value;
587    /// #
588    /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]);
589    ///
590    /// assert!(value.is_any_bytes_type());
591    ///
592    /// let value = Value::Identifier([1u8;32]);
593    ///
594    /// assert!(value.is_any_bytes_type());
595    ///
596    /// let value = Value::Bytes20([1u8;20]);
597    ///
598    /// assert!(value.is_any_bytes_type());
599    ///
600    /// let value = Value::Bytes32([1u8;32]);
601    ///
602    /// assert!(value.is_any_bytes_type());
603    ///
604    /// let value = Value::Bytes36([1u8;36]);
605    ///
606    /// assert!(value.is_any_bytes_type());
607    /// ```
608    pub fn is_any_bytes_type(&self) -> bool {
609        matches!(
610            self,
611            Value::Bytes(_)
612                | Value::Bytes20(_)
613                | Value::Bytes32(_)
614                | Value::Bytes36(_)
615                | Value::Identifier(_)
616        )
617    }
618
619    /// If the `Value` is a `Bytes`, returns a reference to the associated bytes vector.
620    /// Returns None otherwise.
621    ///
622    /// ```
623    /// # use platform_value::Value;
624    /// #
625    /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]);
626    ///
627    /// assert_eq!(std::str::from_utf8(value.as_bytes().unwrap()).unwrap(), "hello");
628    /// ```
629    pub fn as_bytes(&self) -> Option<&Vec<u8>> {
630        match *self {
631            Value::Bytes(ref bytes) => Some(bytes),
632            _ => None,
633        }
634    }
635
636    /// If the `Value` is a `Bytes`, returns a mutable reference to the associated bytes vector.
637    /// Returns None otherwise.
638    ///
639    /// ```
640    /// # use platform_value::Value;
641    /// #
642    /// let mut value = Value::Bytes(vec![104, 101, 108, 108, 111]);
643    /// value.as_bytes_mut().unwrap().clear();
644    ///
645    /// assert_eq!(value, Value::Bytes(vec![]));
646    /// ```
647    pub fn as_bytes_mut(&mut self) -> Option<&mut Vec<u8>> {
648        match *self {
649            Value::Bytes(ref mut bytes) => Some(bytes),
650            _ => None,
651        }
652    }
653
654    /// If the `Value` is a `Bytes`, returns a the associated `Vec<u8>` data as `Ok`.
655    /// Returns `Err(Error::Structure("reason"))` otherwise.
656    ///
657    /// ```
658    /// # use platform_value::{Error, Value};
659    /// #
660    /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]);
661    /// assert_eq!(value.into_bytes(), Ok(vec![104, 101, 108, 108, 111]));
662    ///
663    /// let value = Value::Bool(true);
664    /// assert_eq!(value.into_bytes(), Err(Error::StructureError("value are not bytes".to_string())));
665    /// ```
666    pub fn into_bytes(self) -> Result<Vec<u8>, Error> {
667        match self {
668            Value::Bytes(vec) => Ok(vec),
669            Value::Bytes20(vec) => Ok(vec.to_vec()),
670            Value::Bytes32(vec) => Ok(vec.to_vec()),
671            Value::Bytes36(vec) => Ok(vec.to_vec()),
672            Value::Identifier(vec) => Ok(vec.to_vec()),
673            Value::Array(array) => Ok(array
674                .into_iter()
675                .map(|byte| byte.into_integer())
676                .collect::<Result<Vec<u8>, Error>>()?),
677            _other => Err(Error::StructureError("value are not bytes".to_string())),
678        }
679    }
680
681    /// If the `Value` is a ref to `Bytes`, returns a the associated `Vec<u8>` data as `Ok`.
682    /// Returns `Err(Error::Structure("reason"))` otherwise.
683    ///
684    /// ```
685    /// # use platform_value::{Error, Value};
686    /// #
687    /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]);
688    /// assert_eq!(value.to_bytes(), Ok(vec![104, 101, 108, 108, 111]));
689    ///
690    /// let value = Value::Bool(true);
691    /// assert_eq!(value.to_bytes(), Err(Error::StructureError("ref value are not bytes found bool true instead".to_string())));
692    /// ```
693    pub fn to_bytes(&self) -> Result<Vec<u8>, Error> {
694        match self {
695            Value::Bytes(vec) => Ok(vec.clone()),
696            Value::Bytes20(vec) => Ok(vec.to_vec()),
697            Value::Bytes32(vec) => Ok(vec.to_vec()),
698            Value::Bytes36(vec) => Ok(vec.to_vec()),
699            Value::Identifier(vec) => Ok(vec.to_vec()),
700            Value::Array(array) => Ok(array
701                .iter()
702                .map(|byte| byte.to_integer())
703                .collect::<Result<Vec<u8>, Error>>()?),
704            other => Err(Error::StructureError(format!(
705                "ref value are not bytes found {} instead",
706                other
707            ))),
708        }
709    }
710
711    /// If the `Value` is a ref to `Bytes`, returns a the associated `BinaryData` data as `Ok`.
712    /// BinaryData wraps Vec<u8>
713    /// Returns `Err(Error::Structure("reason"))` otherwise.
714    ///
715    /// ```
716    /// # use platform_value::{BinaryData, Error, Value};
717    /// #
718    /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]);
719    /// assert_eq!(value.to_binary_data(), Ok(BinaryData::new(vec![104, 101, 108, 108, 111])));
720    ///
721    /// let value = Value::Bool(true);
722    /// assert_eq!(value.to_binary_data(), Err(Error::StructureError("ref value are not bytes found bool true instead".to_string())));
723    /// ```
724    pub fn to_binary_data(&self) -> Result<BinaryData, Error> {
725        match self {
726            Value::Bytes(vec) => Ok(BinaryData::new(vec.clone())),
727            Value::Bytes20(vec) => Ok(BinaryData::new(vec.to_vec())),
728            Value::Bytes32(vec) => Ok(BinaryData::new(vec.to_vec())),
729            Value::Bytes36(vec) => Ok(BinaryData::new(vec.to_vec())),
730            Value::Identifier(vec) => Ok(BinaryData::new(vec.to_vec())),
731            Value::Array(array) => Ok(BinaryData::new(
732                array
733                    .iter()
734                    .map(|byte| byte.to_integer())
735                    .collect::<Result<Vec<u8>, Error>>()?,
736            )),
737            other => Err(Error::StructureError(format!(
738                "ref value are not bytes found {} instead",
739                other
740            ))),
741        }
742    }
743
744    /// If the `Value` is a ref to `Bytes`, returns a the associated `&[u8]` data as `Ok`.
745    /// Returns `Err(Error::Structure("reason"))` otherwise.
746    ///
747    /// ```
748    /// # use platform_value::{Error, Value};
749    /// #
750    /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]);
751    /// assert_eq!(value.as_bytes_slice(), Ok(vec![104, 101, 108, 108, 111].as_slice()));
752    ///
753    /// let value = Value::Bool(true);
754    /// assert_eq!(value.as_bytes_slice(), Err(Error::StructureError("ref value are not bytes slice".to_string())));
755    /// ```
756    pub fn as_bytes_slice(&self) -> Result<&[u8], Error> {
757        match self {
758            Value::Bytes(vec) => Ok(vec),
759            Value::Bytes20(vec) => Ok(vec.as_slice()),
760            Value::Bytes32(vec) => Ok(vec.as_slice()),
761            Value::Bytes36(vec) => Ok(vec.as_slice()),
762            Value::Identifier(vec) => Ok(vec.as_slice()),
763            _other => Err(Error::StructureError(
764                "ref value are not bytes slice".to_string(),
765            )),
766        }
767    }
768
769    /// Returns true if the `Value` is a `Float`. Returns false otherwise.
770    ///
771    /// ```
772    /// # use platform_value::Value;
773    /// #
774    /// let value = Value::Float(17.0.into());
775    ///
776    /// assert!(value.is_float());
777    /// ```
778    pub fn is_float(&self) -> bool {
779        self.as_float().is_some()
780    }
781
782    /// If the `Value` is a `Float`, returns a reference to the associated float data.
783    /// Returns None otherwise.
784    ///
785    /// ```
786    /// # use platform_value::Value;
787    /// #
788    /// let value = Value::Float(17.0.into());
789    ///
790    /// // We can read the float number
791    /// assert_eq!(value.as_float().unwrap(), 17.0_f64);
792    /// ```
793    pub fn as_float(&self) -> Option<f64> {
794        match *self {
795            Value::U128(int) => Some(int as f64),
796            Value::I128(int) => Some(int as f64),
797            Value::U64(int) => Some(int as f64),
798            Value::I64(int) => Some(int as f64),
799            Value::U32(int) => Some(int as f64),
800            Value::I32(int) => Some(int as f64),
801            Value::U16(int) => Some(int as f64),
802            Value::I16(int) => Some(int as f64),
803            Value::U8(int) => Some(int as f64),
804            Value::I8(int) => Some(int as f64),
805            Value::Float(f) => Some(f),
806            _ => None,
807        }
808    }
809
810    /// If the `Value` is a `Float`, returns a the associated `f64` data as `Ok`.
811    /// Returns `Err(Error::Structure("reason"))` otherwise.
812    ///
813    /// ```
814    /// # use platform_value::{Error, Value};
815    /// #
816    /// let value = Value::Float(17.);
817    /// assert_eq!(value.into_float(), Ok(17.));
818    ///
819    /// let value = Value::Bool(true);
820    /// assert_eq!(value.into_float(), Err(Error::StructureError("value is not a float".to_string())));
821    /// ```
822    pub fn into_float(self) -> Result<f64, Error> {
823        match self {
824            Value::U128(int) => Ok(int as f64),
825            Value::I128(int) => Ok(int as f64),
826            Value::U64(int) => Ok(int as f64),
827            Value::I64(int) => Ok(int as f64),
828            Value::U32(int) => Ok(int as f64),
829            Value::I32(int) => Ok(int as f64),
830            Value::U16(int) => Ok(int as f64),
831            Value::I16(int) => Ok(int as f64),
832            Value::U8(int) => Ok(int as f64),
833            Value::I8(int) => Ok(int as f64),
834            Value::Float(f) => Ok(f),
835            _other => Err(Error::StructureError("value is not a float".to_string())),
836        }
837    }
838
839    /// If the `Value` is a `Float`, returns a the associated `f64` data as `Ok`.
840    /// Returns `Err(Error::Structure("reason"))` otherwise.
841    ///
842    /// ```
843    /// # use platform_value::{Error, Value};
844    /// #
845    /// let value = Value::Float(17.);
846    /// assert_eq!(value.to_float(), Ok(17.));
847    ///
848    /// let value = Value::Bool(true);
849    /// assert_eq!(value.to_float(), Err(Error::StructureError("value is not a float".to_string())));
850    /// ```
851    pub fn to_float(&self) -> Result<f64, Error> {
852        match self {
853            Value::U128(int) => Ok(*int as f64),
854            Value::I128(int) => Ok(*int as f64),
855            Value::U64(int) => Ok(*int as f64),
856            Value::I64(int) => Ok(*int as f64),
857            Value::U32(int) => Ok(*int as f64),
858            Value::I32(int) => Ok(*int as f64),
859            Value::U16(int) => Ok(*int as f64),
860            Value::I16(int) => Ok(*int as f64),
861            Value::U8(int) => Ok(*int as f64),
862            Value::I8(int) => Ok(*int as f64),
863            Value::Float(f) => Ok(*f),
864            _other => Err(Error::StructureError("value is not a float".to_string())),
865        }
866    }
867
868    /// Returns true if the `Value` is a `Text`. Returns false otherwise.
869    ///
870    /// ```
871    /// # use platform_value::Value;
872    /// #
873    /// let value = Value::Text(String::from("hello"));
874    ///
875    /// assert!(value.is_text());
876    /// ```
877    pub fn is_text(&self) -> bool {
878        self.as_text().is_some()
879    }
880
881    /// If the `Value` is a `Text`, returns a reference to the associated `String` data.
882    /// Returns None otherwise.
883    ///
884    /// ```
885    /// # use platform_value::Value;
886    /// #
887    /// let value = Value::Text(String::from("hello"));
888    ///
889    /// // We can read the String
890    /// assert_eq!(value.as_text().unwrap(), "hello");
891    /// ```
892    pub fn as_text(&self) -> Option<&str> {
893        match *self {
894            Value::Text(ref s) => Some(s),
895            _ => None,
896        }
897    }
898
899    /// If the `Value` is a `Text`, returns a mutable reference to the associated `String` data.
900    /// Returns None otherwise.
901    ///
902    /// ```
903    /// # use platform_value::Value;
904    /// #
905    /// let mut value = Value::Text(String::from("hello"));
906    /// value.as_text_mut().unwrap().clear();
907    ///
908    /// assert_eq!(value.as_text().unwrap(), &String::from(""));
909    /// ```
910    pub fn as_text_mut(&mut self) -> Option<&mut String> {
911        match *self {
912            Value::Text(ref mut s) => Some(s),
913            _ => None,
914        }
915    }
916
917    /// If the `Value` is a `String`, returns a the associated `String` data as `Ok`.
918    /// Returns `Err(Error::Structure("reason"))` otherwise.
919    ///
920    /// ```
921    /// # use platform_value::{Error, Value};
922    /// #
923    /// let value = Value::Text(String::from("hello"));
924    /// assert_eq!(value.into_text().as_deref(), Ok("hello"));
925    ///
926    /// let value = Value::Bool(true);
927    /// assert_eq!(value.into_text(), Err(Error::StructureError("value is not a string".to_string())));
928    /// ```
929    pub fn into_text(self) -> Result<String, Error> {
930        match self {
931            Value::Text(s) => Ok(s),
932            _other => Err(Error::StructureError("value is not a string".to_string())),
933        }
934    }
935
936    /// If the `Value` is a `String`, returns a the associated `String` data as `Ok`.
937    /// Returns `Err(Error::Structure("reason"))` otherwise.
938    ///
939    /// ```
940    /// # use platform_value::{Error, Value};
941    /// #
942    /// let value = Value::Text(String::from("hello"));
943    /// assert_eq!(value.to_text().as_deref(), Ok("hello"));
944    ///
945    /// let value = Value::Bool(true);
946    /// assert_eq!(value.to_text(), Err(Error::StructureError("value is not a string".to_string())));
947    /// ```
948    pub fn to_text(&self) -> Result<String, Error> {
949        match self {
950            Value::Text(s) => Ok(s.clone()),
951            _other => Err(Error::StructureError("value is not a string".to_string())),
952        }
953    }
954
955    /// If the `Value` is a `String`, returns a the associated `&str` data as `Ok`.
956    /// Returns `Err(Error::Structure("reason"))` otherwise.
957    ///
958    /// ```
959    /// # use platform_value::{Error, Value};
960    /// #
961    /// let value = Value::Text(String::from("hello"));
962    /// assert_eq!(value.to_str(), Ok("hello"));
963    ///
964    /// let value = Value::Bool(true);
965    /// assert_eq!(value.to_str(), Err(Error::StructureError("value is not a string".to_string())));
966    /// ```
967    pub fn to_str(&self) -> Result<&str, Error> {
968        match self {
969            Value::Text(s) => Ok(s),
970            _other => Err(Error::StructureError("value is not a string".to_string())),
971        }
972    }
973
974    /// If the `Value` is a `String`, returns a reference to the associated `String` data as `Ok`.
975    /// Returns `Err(Error::Structure("reason"))` otherwise.
976    ///
977    /// ```
978    /// # use platform_value::{Error, Value};
979    /// #
980    /// let value = Value::Text(String::from("hello"));
981    /// assert_eq!(value.as_str(), Some("hello"));
982    ///
983    /// let value = Value::Bool(true);
984    /// assert_eq!(value.as_str(), None);
985    /// ```
986    pub fn as_str(&self) -> Option<&str> {
987        match self {
988            Value::Text(s) => Some(s),
989            _ => None,
990        }
991    }
992
993    /// Returns true if the `Value` is a `Bool`. Returns false otherwise.
994    ///
995    /// ```
996    /// # use platform_value::Value;
997    /// #
998    /// let value = Value::Bool(false);
999    ///
1000    /// assert!(value.is_bool());
1001    /// ```
1002    pub fn is_bool(&self) -> bool {
1003        self.as_bool().is_some()
1004    }
1005
1006    /// If the `Value` is a `Bool`, returns a copy of the associated boolean value. Returns None
1007    /// otherwise.
1008    ///
1009    /// ```
1010    /// # use platform_value::Value;
1011    /// #
1012    /// let value = Value::Bool(false);
1013    ///
1014    /// assert_eq!(value.as_bool().unwrap(), false);
1015    /// ```
1016    pub fn as_bool(&self) -> Option<bool> {
1017        match *self {
1018            Value::Bool(b) => Some(b),
1019            _ => None,
1020        }
1021    }
1022
1023    /// If the `Value` is a `Bool`, returns a the associated `bool` data as `Ok`.
1024    /// Returns `Err(Error::Structure("reason"))` otherwise.
1025    ///
1026    /// ```
1027    /// # use platform_value::{Error, Value};
1028    /// #
1029    /// let value = Value::Bool(false);
1030    /// assert_eq!(value.into_bool(), Ok(false));
1031    ///
1032    /// let value = Value::Float(17.);
1033    /// assert_eq!(value.into_bool(), Err(Error::StructureError("value is not a bool".to_string())));
1034    /// ```
1035    pub fn into_bool(self) -> Result<bool, Error> {
1036        match self {
1037            Value::Bool(b) => Ok(b),
1038            _other => Err(Error::StructureError("value is not a bool".to_string())),
1039        }
1040    }
1041
1042    /// If the `Value` is a `Bool`, returns a the associated `bool` data as `Ok`.
1043    /// Returns `Err(Error::Structure("reason"))` otherwise.
1044    ///
1045    /// ```
1046    /// # use platform_value::{Error, Value};
1047    /// #
1048    /// let value = Value::Bool(false);
1049    /// assert_eq!(value.to_bool(), Ok(false));
1050    ///
1051    /// let value = Value::Float(17.);
1052    /// assert_eq!(value.to_bool(), Err(Error::StructureError("value is not a bool".to_string())));
1053    /// ```
1054    pub fn to_bool(&self) -> Result<bool, Error> {
1055        match self {
1056            Value::Bool(b) => Ok(*b),
1057            _other => Err(Error::StructureError("value is not a bool".to_string())),
1058        }
1059    }
1060
1061    /// Returns true if the `Value` is a `Null`. Returns false otherwise.
1062    ///
1063    /// ```
1064    /// # use platform_value::Value;
1065    /// #
1066    /// let value = Value::Null;
1067    ///
1068    /// assert!(value.is_null());
1069    /// ```
1070    pub fn is_null(&self) -> bool {
1071        matches!(self, Value::Null)
1072    }
1073
1074    /// Returns true if the `Value` is an Array. Returns false otherwise.
1075    ///
1076    /// ```
1077    /// # use platform_value::Value;
1078    /// #
1079    /// let value = Value::Array(
1080    ///     vec![
1081    ///         Value::Text(String::from("foo")),
1082    ///         Value::Text(String::from("bar"))
1083    ///     ]
1084    /// );
1085    ///
1086    /// assert!(value.is_array());
1087    /// ```
1088    pub fn is_array(&self) -> bool {
1089        self.as_array().is_some()
1090    }
1091
1092    /// If the `Value` is an Array, returns a reference to the associated vector. Returns None
1093    /// otherwise.
1094    ///
1095    /// ```
1096    /// # use platform_value::Value;
1097    /// #
1098    /// let value = Value::Array(
1099    ///     vec![
1100    ///         Value::Text(String::from("foo")),
1101    ///         Value::Text(String::from("bar"))
1102    ///     ]
1103    /// );
1104    ///
1105    /// // The length of `value` is 2 elements.
1106    /// assert_eq!(value.as_array().unwrap().len(), 2);
1107    /// ```
1108    pub fn as_array(&self) -> Option<&Vec<Value>> {
1109        match *self {
1110            Value::Array(ref array) => Some(array),
1111            _ => None,
1112        }
1113    }
1114
1115    /// If the `Value` is an Array, returns a mutable reference to the associated vector.
1116    /// Returns None otherwise.
1117    ///
1118    /// ```
1119    /// # use platform_value::Value;
1120    /// #
1121    /// let mut value = Value::Array(
1122    ///     vec![
1123    ///         Value::Text(String::from("foo")),
1124    ///         Value::Text(String::from("bar"))
1125    ///     ]
1126    /// );
1127    ///
1128    /// value.as_array_mut().unwrap().clear();
1129    /// assert_eq!(value, Value::Array(vec![]));
1130    /// ```
1131    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
1132        match *self {
1133            Value::Array(ref mut list) => Some(list),
1134            _ => None,
1135        }
1136    }
1137
1138    /// If the `Value` is an Array, returns a mutable reference to the associated vector.
1139    /// Returns None otherwise.
1140    ///
1141    /// ```
1142    /// # use platform_value::Value;
1143    /// #
1144    /// let mut value = Value::Array(
1145    ///     vec![
1146    ///         Value::Text(String::from("foo")),
1147    ///         Value::Text(String::from("bar"))
1148    ///     ]
1149    /// );
1150    ///
1151    /// value.to_array_mut().unwrap().clear();
1152    /// assert_eq!(value, Value::Array(vec![]));
1153    /// ```
1154    pub fn to_array_mut(&mut self) -> Result<&mut Vec<Value>, Error> {
1155        match self {
1156            Value::Array(vec) => Ok(vec),
1157            other => Err(Error::StructureError(format!(
1158                "value is not a mut array got {}",
1159                other
1160            ))),
1161        }
1162    }
1163
1164    /// If the `Value` is a `Array`, returns a the associated `&[Value]` slice as `Ok`.
1165    /// Returns `Err(Error::Structure("reason"))` otherwise.
1166    ///
1167    /// ```
1168    /// # use platform_value::{Value, Error};
1169    /// #
1170    /// let mut value = Value::Array(
1171    ///     vec![
1172    ///         Value::U64(17),
1173    ///         Value::Float(18.),
1174    ///     ]
1175    /// );
1176    /// assert_eq!(value.to_array_slice(), Ok(vec![Value::U64(17), Value::Float(18.)].as_slice()));
1177    ///
1178    /// let value = Value::Bool(true);
1179    /// assert_eq!(value.to_array_slice(), Err(Error::StructureError("value is not an array got bool true".to_string())));
1180    /// ```
1181    pub fn to_array_slice(&self) -> Result<&[Value], Error> {
1182        match self {
1183            Value::Array(vec) => Ok(vec.as_slice()),
1184            other => Err(Error::StructureError(format!(
1185                "value is not an array got {}",
1186                other
1187            ))),
1188        }
1189    }
1190
1191    /// If the `Value` is a `Array`, returns a the associated `Vec<&Value>` array as `Ok`.
1192    /// Returns `Err(Error::Structure("reason"))` otherwise.
1193    ///
1194    /// ```
1195    /// # use platform_value::{Value, Error};
1196    /// #
1197    /// let mut value = Value::Array(
1198    ///     vec![
1199    ///         Value::U64(17),
1200    ///         Value::Float(18.),
1201    ///     ]
1202    /// );
1203    /// assert_eq!(value.to_array_ref(), Ok(&vec![Value::U64(17), Value::Float(18.)]));
1204    ///
1205    /// let value = Value::Bool(true);
1206    /// assert_eq!(value.to_array_ref(), Err(Error::StructureError("value is not an array got bool true".to_string())));
1207    /// ```
1208    pub fn to_array_ref(&self) -> Result<&Vec<Value>, Error> {
1209        match self {
1210            Value::Array(vec) => Ok(vec),
1211            other => Err(Error::StructureError(format!(
1212                "value is not an array got {}",
1213                other
1214            ))),
1215        }
1216    }
1217
1218    /// If the `Value` is a `Array`, returns a the associated `Vec<Value>` data as `Ok`.
1219    /// Returns `Err(Error::Structure("reason"))` otherwise.
1220    ///
1221    /// ```
1222    /// # use platform_value::{Value, Error};
1223    /// #
1224    /// let mut value = Value::Array(
1225    ///     vec![
1226    ///         Value::U64(17),
1227    ///         Value::Float(18.),
1228    ///     ]
1229    /// );
1230    /// assert_eq!(value.to_array_owned(), Ok(vec![Value::U64(17), Value::Float(18.)]));
1231    ///
1232    /// let value = Value::Bool(true);
1233    /// assert_eq!(value.to_array_owned(), Err(Error::StructureError("value is not an owned array got bool true".to_string())));
1234    /// ```
1235    pub fn to_array_owned(&self) -> Result<Vec<Value>, Error> {
1236        match self {
1237            Value::Array(vec) => Ok(vec.clone()),
1238            other => Err(Error::StructureError(format!(
1239                "value is not an owned array got {}",
1240                other
1241            ))),
1242        }
1243    }
1244
1245    /// If the `Value` is a `Array`, returns a the associated `Vec<Value>` data as `Ok`.
1246    /// Returns `Err(Error::Structure("reason"))` otherwise.
1247    ///
1248    /// ```
1249    /// # use platform_value::{Value, Error};
1250    /// #
1251    /// let mut value = Value::Array(
1252    ///     vec![
1253    ///         Value::U64(17),
1254    ///         Value::Float(18.),
1255    ///     ]
1256    /// );
1257    /// assert_eq!(value.into_array(), Ok(vec![Value::U64(17), Value::Float(18.)]));
1258    ///
1259    /// let value = Value::Bool(true);
1260    /// assert_eq!(value.into_array(), Err(Error::StructureError("value is not an array (into) got bool true".to_string())));
1261    /// ```
1262    pub fn into_array(self) -> Result<Vec<Value>, Error> {
1263        match self {
1264            Value::Array(vec) => Ok(vec),
1265            other => Err(Error::StructureError(format!(
1266                "value is not an array (into) got {}",
1267                other
1268            ))),
1269        }
1270    }
1271
1272    /// If the `Value` is a `Array`, returns a the associated `Vec<Value>` data as `Ok`.
1273    /// Returns `Err(Error::Structure("reason"))` otherwise.
1274    ///
1275    /// ```
1276    /// # use platform_value::{Value, Error};
1277    /// #
1278    /// let mut value = Value::Array(
1279    ///     vec![
1280    ///         Value::U64(17),
1281    ///         Value::Float(18.),
1282    ///     ]
1283    /// );
1284    /// assert_eq!(value.as_slice(), Ok(vec![Value::U64(17), Value::Float(18.)].as_slice()));
1285    ///
1286    /// let value = Value::Bool(true);
1287    /// assert_eq!(value.as_slice(), Err(Error::StructureError("value is not a slice got bool true".to_string())));
1288    /// ```
1289    pub fn as_slice(&self) -> Result<&[Value], Error> {
1290        match self {
1291            Value::Array(vec) => Ok(vec),
1292            other => Err(Error::StructureError(format!(
1293                "value is not a slice got {}",
1294                other
1295            ))),
1296        }
1297    }
1298
1299    /// Returns true if the `Value` is a Map. Returns false otherwise.
1300    ///
1301    /// ```
1302    /// # use platform_value::Value;
1303    /// #
1304    /// let value = Value::Map(
1305    ///     vec![
1306    ///         (Value::Text(String::from("foo")), Value::Text(String::from("bar")))
1307    ///     ]
1308    /// );
1309    ///
1310    /// assert!(value.is_map());
1311    /// ```
1312    pub fn is_map(&self) -> bool {
1313        self.as_map().is_some()
1314    }
1315
1316    /// If the `Value` is a Map, returns a reference to the associated Map data. Returns None
1317    /// otherwise.
1318    ///
1319    /// ```
1320    /// # use platform_value::Value;
1321    /// #
1322    /// let value = Value::Map(
1323    ///     vec![
1324    ///         (Value::Text(String::from("foo")), Value::Text(String::from("bar")))
1325    ///     ]
1326    /// );
1327    ///
1328    /// // The length of data is 1 entry (1 key/value pair).
1329    /// assert_eq!(value.as_map().unwrap().len(), 1);
1330    ///
1331    /// // The content of the first element is what we expect
1332    /// assert_eq!(
1333    ///     value.as_map().unwrap().get(0).unwrap(),
1334    ///     &(Value::Text(String::from("foo")), Value::Text(String::from("bar")))
1335    /// );
1336    /// ```
1337    pub fn as_map(&self) -> Option<&Vec<(Value, Value)>> {
1338        match *self {
1339            Value::Map(ref map) => Some(map),
1340            _ => None,
1341        }
1342    }
1343
1344    /// If the `Value` is a Map, returns a mutable reference to the associated Map Data.
1345    /// Returns None otherwise.
1346    ///
1347    /// ```
1348    /// # use platform_value::Value;
1349    /// #
1350    /// let mut value = Value::Map(
1351    ///     vec![
1352    ///         (Value::Text(String::from("foo")), Value::Text(String::from("bar")))
1353    ///     ]
1354    /// );
1355    ///
1356    /// value.as_map_mut().unwrap().clear();
1357    /// assert_eq!(value, Value::Map(vec![]));
1358    /// assert_eq!(value.as_map().unwrap().len(), 0);
1359    /// ```
1360    pub fn as_map_mut(&mut self) -> Option<&mut Vec<(Value, Value)>> {
1361        match *self {
1362            Value::Map(ref mut map) => Some(map),
1363            _ => None,
1364        }
1365    }
1366
1367    /// If the `Value` is a Map, returns a mutable reference to the associated Map Data.
1368    /// Returns Err otherwise.
1369    ///
1370    /// ```
1371    /// # use platform_value::Value;
1372    /// #
1373    /// let mut value = Value::Map(
1374    ///     vec![
1375    ///         (Value::Text(String::from("foo")), Value::Text(String::from("bar")))
1376    ///     ]
1377    /// );
1378    ///
1379    /// value.to_map_mut().unwrap().clear();
1380    /// assert_eq!(value, Value::Map(vec![]));
1381    /// assert_eq!(value.as_map().unwrap().len(), 0);
1382    /// ```
1383    pub fn to_map_mut(&mut self) -> Result<&mut ValueMap, Error> {
1384        match *self {
1385            Value::Map(ref mut map) => Ok(map),
1386            _ => Err(Error::StructureError("value is not a map".to_string())),
1387        }
1388    }
1389
1390    /// If the `Value` is a `Map`, returns a the associated ValueMap which is a `Vec<(Value, Value)>`
1391    /// data as `Ok`.
1392    /// Returns `Err(Error::Structure("reason"))` otherwise.
1393    ///
1394    /// ```
1395    /// # use platform_value::{Error, Value};
1396    /// #
1397    /// let mut value = Value::Map(
1398    ///     vec![
1399    ///         (Value::Text(String::from("key")), Value::Float(18.)),
1400    ///     ]
1401    /// );
1402    /// assert_eq!(value.into_map(), Ok(vec![(Value::Text(String::from("key")), Value::Float(18.))]));
1403    ///
1404    /// let value = Value::Bool(true);
1405    /// assert_eq!(value.into_map(), Err(Error::StructureError("value is not a map".to_string())))
1406    /// ```
1407    pub fn into_map(self) -> Result<ValueMap, Error> {
1408        match self {
1409            Value::Map(map) => Ok(map),
1410            _other => Err(Error::StructureError("value is not a map".to_string())),
1411        }
1412    }
1413
1414    /// If the `Value` is a `Map`, returns a the associated ValueMap which is a `Vec<(Value, Value)>`
1415    /// data as `Ok`.
1416    /// Returns `Err(Error::Structure("reason"))` otherwise.
1417    ///
1418    /// ```
1419    /// # use platform_value::{Error, Value};
1420    /// #
1421    /// let mut value = Value::Map(
1422    ///     vec![
1423    ///         (Value::Text(String::from("key")), Value::Float(18.)),
1424    ///     ]
1425    /// );
1426    /// assert_eq!(value.to_map(), Ok(&vec![(Value::Text(String::from("key")), Value::Float(18.))]));
1427    ///
1428    /// let value = Value::Bool(true);
1429    /// assert_eq!(value.to_map(), Err(Error::StructureError("value is not a map".to_string())))
1430    /// ```
1431    pub fn to_map(&self) -> Result<&ValueMap, Error> {
1432        match self {
1433            Value::Map(map) => Ok(map),
1434            _other => Err(Error::StructureError("value is not a map".to_string())),
1435        }
1436    }
1437
1438    /// If the `Value` is a `Map`, returns the associated ValueMap ref which is a `&Vec<(Value, Value)>`
1439    /// data as `Ok`.
1440    /// Returns `Err(Error::Structure("reason"))` otherwise.
1441    ///
1442    /// ```
1443    /// # use platform_value::{Error, Value};
1444    /// #
1445    /// let mut value = Value::Map(
1446    ///     vec![
1447    ///         (Value::Text(String::from("key")), Value::Float(18.)),
1448    ///     ]
1449    /// );
1450    /// assert_eq!(value.to_map_ref(), Ok(&vec![(Value::Text(String::from("key")), Value::Float(18.))]));
1451    ///
1452    /// let value = Value::Bool(true);
1453    /// assert_eq!(value.to_map_ref(), Err(Error::StructureError("value is not a map".to_string())))
1454    /// ```
1455    pub fn to_map_ref(&self) -> Result<&ValueMap, Error> {
1456        match self {
1457            Value::Map(map) => Ok(map),
1458            _other => Err(Error::StructureError("value is not a map".to_string())),
1459        }
1460    }
1461
1462    /// If the `Value` is a `Map`, returns the associated ValueMap ref which is a `&Vec<(Value, Value)>`
1463    /// data as `Ok`.
1464    /// Returns `Err(Error::Structure("reason"))` otherwise.
1465    ///
1466    /// ```
1467    /// # use platform_value::{Error, Value};
1468    /// #
1469    /// let mut value = Value::Map(
1470    ///     vec![
1471    ///         (Value::Text(String::from("key")), Value::Float(18.)),
1472    ///     ]
1473    /// );
1474    /// assert_eq!(value.as_map_mut_ref(), Ok(&mut vec![(Value::Text(String::from("key")), Value::Float(18.))]));
1475    ///
1476    /// let mut value = Value::Bool(true);
1477    /// assert_eq!(value.as_map_mut_ref(), Err(Error::StructureError("value is not a map".to_string())))
1478    /// ```
1479    pub fn as_map_mut_ref(&mut self) -> Result<&mut ValueMap, Error> {
1480        match self {
1481            Value::Map(map) => Ok(map),
1482            _other => Err(Error::StructureError("value is not a map".to_string())),
1483        }
1484    }
1485
1486    /// Returns the numeric value as `i128` if this is any signed /
1487    /// unsigned integer variant **and** the conversion is loss-less.
1488    #[inline]
1489    fn as_i128_unified(&self) -> Option<i128> {
1490        use Value::*;
1491        match self {
1492            I128(v) => Some(*v),
1493            I64(v) => Some(*v as i128),
1494            I32(v) => Some(*v as i128),
1495            I16(v) => Some(*v as i128),
1496            I8(v) => Some(*v as i128),
1497
1498            U128(v) if *v <= i128::MAX as u128 => Some(*v as i128),
1499            U64(v) => Some(*v as i128),
1500            U32(v) => Some(*v as i128),
1501            U16(v) => Some(*v as i128),
1502            U8(v) => Some(*v as i128),
1503
1504            _ => None,
1505        }
1506    }
1507
1508    /// Returns the first container depth greater than `max_depth`.
1509    ///
1510    /// Maps and arrays each add one level, including a container at the root. Map keys are
1511    /// included because they are also attacker-controlled [`Value`] instances. The traversal is
1512    /// iterative so checking an invalid value cannot itself consume attacker-selected stack depth.
1513    pub fn first_depth_exceeding(&self, max_depth: usize) -> Option<usize> {
1514        let mut pending = vec![(self, 0usize)];
1515
1516        while let Some((value, parent_depth)) = pending.pop() {
1517            let children: &[_] = match value {
1518                Value::Array(values) => values,
1519                Value::Map(map) => {
1520                    let depth = parent_depth + 1;
1521                    if depth > max_depth {
1522                        return Some(depth);
1523                    }
1524                    for (key, value) in map.iter().rev() {
1525                        pending.push((value, depth));
1526                        pending.push((key, depth));
1527                    }
1528                    continue;
1529                }
1530                _ => continue,
1531            };
1532
1533            let depth = parent_depth + 1;
1534            if depth > max_depth {
1535                return Some(depth);
1536            }
1537            pending.extend(children.iter().rev().map(|value| (value, depth)));
1538        }
1539
1540        None
1541    }
1542
1543    /// Determines whether any scalar data in this value is larger than `size`.
1544    ///
1545    /// Container traversal is iterative to keep stack use independent of attacker-controlled
1546    /// nesting. The reported map key or array child remains the outermost value that identifies
1547    /// the oversized field, matching the previous recursive behavior.
1548    pub fn has_data_larger_than(&self, size: u32) -> Option<(Option<&Value>, u32)> {
1549        let mut pending = vec![(self, None)];
1550
1551        while let Some((value, reported_value)) = pending.pop() {
1552            let actual_size = match value {
1553                Value::U128(_) | Value::I128(_) => (size < 16).then_some(16),
1554                Value::U64(_) | Value::I64(_) | Value::Float(_) => (size < 8).then_some(8),
1555                Value::U32(_) | Value::I32(_) => (size < 4).then_some(4),
1556                Value::U16(_) | Value::I16(_) => (size < 2).then_some(2),
1557                Value::U8(_) | Value::I8(_) | Value::EnumU8(_) | Value::Bool(_) | Value::Null => {
1558                    (size < 1).then_some(1)
1559                }
1560                Value::Bytes(bytes) => (bytes.len() > size as usize).then_some(bytes.len() as u32),
1561                Value::Bytes20(_) => (size < 20).then_some(20),
1562                Value::Bytes32(_) | Value::Identifier(_) => (size < 32).then_some(32),
1563                Value::Bytes36(_) => (size < 36).then_some(36),
1564                Value::EnumString(strings) => strings
1565                    .iter()
1566                    .map(|string| string.len())
1567                    .max()
1568                    .filter(|actual_size| *actual_size > size as usize)
1569                    .map(|actual_size| actual_size as u32),
1570                Value::Text(string) => {
1571                    (string.len() > size as usize).then_some(string.len() as u32)
1572                }
1573                Value::Array(values) => {
1574                    for value in values.iter().rev() {
1575                        pending.push((value, reported_value.or(Some(value))));
1576                    }
1577                    continue;
1578                }
1579                Value::Map(map) => {
1580                    for (key, value) in map.iter().rev() {
1581                        pending.push((value, reported_value.or(Some(key))));
1582                    }
1583                    continue;
1584                }
1585            };
1586
1587            if let Some(actual_size) = actual_size {
1588                return Some((reported_value, actual_size));
1589            }
1590        }
1591
1592        None
1593    }
1594}
1595
1596macro_rules! implfrom {
1597    ($($v:ident($t:ty)),+ $(,)?) => {
1598        $(
1599            impl From<$t> for Value {
1600                #[inline]
1601                fn from(value: $t) -> Self {
1602                    Self::$v(value.into())
1603                }
1604            }
1605        )+
1606    };
1607}
1608
1609macro_rules! impltryinto {
1610    ($($t:ty),+ $(,)?) => {
1611        $(
1612            impl TryFrom<Value> for $t {
1613                type Error = Error;
1614                #[inline]
1615                fn try_from(value: Value) -> Result<Self, Self::Error> {
1616                    value.to_integer()
1617                }
1618            }
1619        )+
1620    };
1621}
1622
1623impltryinto! {
1624    u128,
1625    i128,
1626    u64,
1627    i64,
1628    u32,
1629    i32,
1630    u16,
1631    i16,
1632    u8,
1633    i8,
1634}
1635
1636implfrom! {
1637    U128(u128),
1638    I128(i128),
1639    U64(u64),
1640    I64(i64),
1641    U32(u32),
1642    I32(i32),
1643    U16(u16),
1644    I16(i16),
1645    U8(u8),
1646    I8(i8),
1647
1648    Bytes(Vec<u8>),
1649    Bytes(&[u8]),
1650    Bytes32([u8;32]),
1651    Bytes20([u8;20]),
1652    Bytes36([u8;36]),
1653
1654    Float(f64),
1655    Float(f32),
1656
1657    Text(String),
1658    Text(&str),
1659
1660    Bool(bool),
1661
1662    Array(&[Value]),
1663    Array(Vec<Value>),
1664
1665    Map(&[(Value, Value)]),
1666    Map(Vec<(Value, Value)>),
1667}
1668
1669impl<const N: usize> From<[(Value, Value); N]> for Value {
1670    /// Converts a `[(Value, Value); N]` into a `Value`.
1671    ///
1672    /// ```
1673    /// use platform_value::Value;
1674    ///
1675    /// let map1 = Value::from([(Value::from(1), Value::from(2)), (Value::from(3), Value::from(4))]);
1676    /// let map2: Value = [(Value::from(1), Value::from(2)), (Value::from(3), Value::from(4))].into();
1677    /// assert_eq!(map1, map2);
1678    /// ```
1679    fn from(arr: [(Value, Value); N]) -> Self {
1680        if N == 0 {
1681            return Value::Map(vec![]);
1682        }
1683
1684        Value::Map(arr.into_iter().collect())
1685    }
1686}
1687
1688impl<const N: usize> From<[(String, Value); N]> for Value {
1689    /// Converts a `[(String, Value); N]` into a `Value`.
1690    ///
1691    /// ```
1692    /// use platform_value::Value;
1693    ///
1694    /// let map1 = Value::from([("1".to_string(), Value::from(2)), ("3".to_string(), Value::from(4))]);
1695    /// let map2: Value = [("1".to_string(), Value::from(2)), ("3".to_string(), Value::from(4))].into();
1696    /// assert_eq!(map1, map2);
1697    /// ```
1698    fn from(mut arr: [(String, Value); N]) -> Self {
1699        if N == 0 {
1700            return Value::Map(vec![]);
1701        }
1702
1703        // use stable sort to preserve the insertion order.
1704        arr.sort_by(|a, b| a.0.cmp(&b.0));
1705        Value::Map(arr.into_iter().map(|(k, v)| (k.into(), v)).collect())
1706    }
1707}
1708
1709impl<const N: usize> From<[(&str, Value); N]> for Value {
1710    /// Converts a `[($str, Value); N]` into a `Value`.
1711    ///
1712    /// ```
1713    /// use platform_value::Value;
1714    ///
1715    /// let map1 = Value::from([("1", Value::from(2)), ("3", Value::from(4))]);
1716    /// let map2: Value = [("1", Value::from(2)), ("3", Value::from(4))].into();
1717    /// assert_eq!(map1, map2);
1718    /// ```
1719    fn from(mut arr: [(&str, Value); N]) -> Self {
1720        if N == 0 {
1721            return Value::Map(vec![]);
1722        }
1723
1724        // use stable sort to preserve the insertion order.
1725        arr.sort_by(|a, b| a.0.cmp(b.0));
1726        Value::Map(arr.into_iter().map(|(k, v)| (k.into(), v)).collect())
1727    }
1728}
1729
1730impl<T> From<BTreeMap<T, &Value>> for Value
1731where
1732    T: Into<Value>,
1733{
1734    fn from(value: BTreeMap<T, &Value>) -> Self {
1735        Value::Map(
1736            value
1737                .into_iter()
1738                .map(|(key, value)| (key.into(), value.clone()))
1739                .collect(),
1740        )
1741    }
1742}
1743
1744impl From<&BTreeMap<String, Value>> for Value {
1745    fn from(value: &BTreeMap<String, Value>) -> Self {
1746        Value::Map(
1747            value
1748                .iter()
1749                .map(|(key, value)| (key.into(), value.clone()))
1750                .collect(),
1751        )
1752    }
1753}
1754
1755impl<T> From<BTreeMap<T, Value>> for Value
1756where
1757    T: Into<Value>,
1758{
1759    fn from(value: BTreeMap<T, Value>) -> Self {
1760        Value::Map(
1761            value
1762                .into_iter()
1763                .map(|(key, value)| (key.into(), value))
1764                .collect(),
1765        )
1766    }
1767}
1768
1769impl<T> From<BTreeMap<T, Option<T>>> for Value
1770where
1771    T: Into<Value>,
1772{
1773    fn from(value: BTreeMap<T, Option<T>>) -> Self {
1774        Value::Map(
1775            value
1776                .into_iter()
1777                .map(|(key, value)| (key.into(), value.map(|a| a.into()).into()))
1778                .collect(),
1779        )
1780    }
1781}
1782
1783impl From<Option<Value>> for Value {
1784    fn from(value: Option<Value>) -> Self {
1785        match value {
1786            None => Value::Null,
1787            Some(value) => value,
1788        }
1789    }
1790}
1791
1792impl From<&String> for Value {
1793    fn from(value: &String) -> Self {
1794        Value::Text(value.clone())
1795    }
1796}
1797
1798impl From<char> for Value {
1799    #[inline]
1800    fn from(value: char) -> Self {
1801        let mut v = String::with_capacity(1);
1802        v.push(value);
1803        Value::Text(v)
1804    }
1805}
1806
1807impl From<Vec<&str>> for Value {
1808    fn from(value: Vec<&str>) -> Self {
1809        Value::Array(value.into_iter().map(|string| string.into()).collect())
1810    }
1811}
1812
1813impl From<&[&str]> for Value {
1814    fn from(value: &[&str]) -> Self {
1815        Value::Array(
1816            value
1817                .iter()
1818                .map(|string| string.to_owned().into())
1819                .collect(),
1820        )
1821    }
1822}
1823impl TryFrom<Value> for Vec<u8> {
1824    type Error = Error;
1825
1826    fn try_from(value: Value) -> Result<Self, Self::Error> {
1827        value.into_bytes()
1828    }
1829}
1830
1831impl TryFrom<Value> for String {
1832    type Error = Error;
1833
1834    fn try_from(value: Value) -> Result<Self, Self::Error> {
1835        value.into_text()
1836    }
1837}