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