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