radix_common/data/manifest/model/
manifest_decimal.rs1use radix_rust::copy_u8_array;
2use sbor::rust::convert::TryFrom;
3#[cfg(not(feature = "alloc"))]
4use sbor::rust::fmt;
5use sbor::rust::vec::Vec;
6use sbor::*;
7
8use crate::data::manifest::*;
9use crate::math::Decimal;
10use crate::*;
11
12pub const DECIMAL_SIZE: usize = Decimal::BITS / 8;
13
14#[cfg_attr(
15 feature = "fuzzing",
16 derive(::arbitrary::Arbitrary, ::serde::Serialize, ::serde::Deserialize)
17)]
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
19pub struct ManifestDecimal(pub [u8; DECIMAL_SIZE]);
20
21#[derive(Debug, Clone, PartialEq, Eq)]
27pub enum ParseManifestDecimalError {
28 InvalidLength,
29}
30
31#[cfg(not(feature = "alloc"))]
32impl std::error::Error for ParseManifestDecimalError {}
33
34#[cfg(not(feature = "alloc"))]
35impl fmt::Display for ParseManifestDecimalError {
36 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37 write!(f, "{:?}", self)
38 }
39}
40
41impl TryFrom<&[u8]> for ManifestDecimal {
46 type Error = ParseManifestDecimalError;
47
48 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
49 if slice.len() != DECIMAL_SIZE {
50 return Err(Self::Error::InvalidLength);
51 }
52 Ok(Self(copy_u8_array(slice)))
53 }
54}
55
56impl ManifestDecimal {
57 pub fn to_vec(&self) -> Vec<u8> {
58 self.0.to_vec()
59 }
60}
61
62manifest_type!(
63 ManifestDecimal,
64 ManifestCustomValueKind::Decimal,
65 DECIMAL_SIZE,
66);
67scrypto_describe_for_manifest_type!(ManifestDecimal, DECIMAL_TYPE, decimal_type_data,);
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use crate::internal_prelude::*;
73
74 #[test]
75 fn manifest_decimal_parse_fail() {
76 let buf = Vec::from_iter(0u8..DECIMAL_SIZE as u8);
77
78 let dec = ManifestDecimal(buf.as_slice().try_into().unwrap());
79 let mut dec_vec = dec.to_vec();
80
81 assert!(ManifestDecimal::try_from(dec_vec.as_slice()).is_ok());
82
83 dec_vec.push(0);
85 let dec_out = ManifestDecimal::try_from(dec_vec.as_slice());
86 assert_matches!(dec_out, Err(ParseManifestDecimalError::InvalidLength));
87
88 #[cfg(not(feature = "alloc"))]
89 println!("Manifest Decimal error: {}", dec_out.unwrap_err());
90 }
91
92 #[test]
93 fn manifest_decimal_encode_decode_fail() {
94 let mut buf = Vec::new();
95 let mut encoder = VecEncoder::<ManifestCustomValueKind>::new(&mut buf, 1);
96 let malformed_value: u8 = 0;
97 encoder.write_slice(&malformed_value.to_le_bytes()).unwrap();
98
99 let mut decoder = VecDecoder::<ManifestCustomValueKind>::new(&buf, 1);
100 let dec_output = decoder
101 .decode_deeper_body_with_value_kind::<ManifestDecimal>(ManifestDecimal::value_kind());
102
103 assert_matches!(dec_output, Err(DecodeError::BufferUnderflow { .. }));
105 }
106}