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}