1use crate::internal_prelude::*;
2
3#[cfg_attr(feature = "fuzzing", derive(::arbitrary::Arbitrary))]
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum ScryptoCustomValue {
6 Reference(Reference),
7 Own(Own),
8 Decimal(Decimal),
9 PreciseDecimal(PreciseDecimal),
10 NonFungibleLocalId(NonFungibleLocalId),
11}
12
13impl CustomValue<ScryptoCustomValueKind> for ScryptoCustomValue {
14 fn get_custom_value_kind(&self) -> ScryptoCustomValueKind {
15 match self {
16 ScryptoCustomValue::Reference(_) => ScryptoCustomValueKind::Reference,
17 ScryptoCustomValue::Own(_) => ScryptoCustomValueKind::Own,
18 ScryptoCustomValue::Decimal(_) => ScryptoCustomValueKind::Decimal,
19 ScryptoCustomValue::PreciseDecimal(_) => ScryptoCustomValueKind::PreciseDecimal,
20 ScryptoCustomValue::NonFungibleLocalId(_) => ScryptoCustomValueKind::NonFungibleLocalId,
21 }
22 }
23}
24
25impl<E: Encoder<ScryptoCustomValueKind>> Encode<ScryptoCustomValueKind, E> for ScryptoCustomValue {
26 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
27 encoder.write_value_kind(ValueKind::Custom(self.get_custom_value_kind()))
28 }
29
30 fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
31 match self {
32 ScryptoCustomValue::Reference(v) => v.encode_body(encoder),
34 ScryptoCustomValue::Own(v) => v.encode_body(encoder),
35 ScryptoCustomValue::Decimal(v) => v.encode_body(encoder),
36 ScryptoCustomValue::PreciseDecimal(v) => v.encode_body(encoder),
37 ScryptoCustomValue::NonFungibleLocalId(v) => v.encode_body(encoder),
38 }
39 }
40}
41
42impl<D: Decoder<ScryptoCustomValueKind>> Decode<ScryptoCustomValueKind, D> for ScryptoCustomValue {
43 fn decode_body_with_value_kind(
44 decoder: &mut D,
45 value_kind: ValueKind<ScryptoCustomValueKind>,
46 ) -> Result<Self, DecodeError> {
47 match value_kind {
48 ValueKind::Custom(cti) => match cti {
49 ScryptoCustomValueKind::Reference => {
50 Reference::decode_body_with_value_kind(decoder, value_kind).map(Self::Reference)
51 }
52 ScryptoCustomValueKind::Own => {
53 Own::decode_body_with_value_kind(decoder, value_kind).map(Self::Own)
54 }
55 ScryptoCustomValueKind::Decimal => {
56 Decimal::decode_body_with_value_kind(decoder, value_kind).map(Self::Decimal)
57 }
58 ScryptoCustomValueKind::PreciseDecimal => {
59 PreciseDecimal::decode_body_with_value_kind(decoder, value_kind)
60 .map(Self::PreciseDecimal)
61 }
62 ScryptoCustomValueKind::NonFungibleLocalId => {
63 NonFungibleLocalId::decode_body_with_value_kind(decoder, value_kind)
64 .map(Self::NonFungibleLocalId)
65 }
66 },
67 _ => Err(DecodeError::UnexpectedCustomValueKind {
68 actual: value_kind.as_u8(),
69 }),
70 }
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use crate::types::NodeId;
78
79 #[test]
80 fn test_custom_types_group1() {
81 let values = (Reference(NodeId([1u8; NodeId::LENGTH])),);
82 let bytes = scrypto_encode(&values).unwrap();
83 assert_eq!(
84 bytes,
85 vec![
86 92, 33, 1, 128, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
90 1, 1, 1, 1, ]
92 );
93 assert_eq!(
94 scrypto_decode::<ScryptoValue>(&bytes).unwrap(),
95 ScryptoValue::Tuple {
96 fields: vec![ScryptoValue::Custom {
97 value: ScryptoCustomValue::Reference(Reference(NodeId([1u8; NodeId::LENGTH]))),
98 },]
99 }
100 );
101 }
102
103 #[test]
104 fn test_custom_types_group2() {
105 let values = (Own(NodeId([1u8; NodeId::LENGTH])),);
106 let bytes = scrypto_encode(&values).unwrap();
107 assert_eq!(
108 bytes,
109 vec![
110 92, 33, 1, 144, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
114 1, 1, 1, 1, ]
116 );
117 assert_eq!(
118 scrypto_decode::<ScryptoValue>(&bytes).unwrap(),
119 ScryptoValue::Tuple {
120 fields: vec![ScryptoValue::Custom {
121 value: ScryptoCustomValue::Own(Own(NodeId([1u8; NodeId::LENGTH]))),
122 },]
123 }
124 );
125 }
126
127 #[test]
128 fn test_custom_types_group4() {
129 let values = (
130 Decimal::ONE,
131 PreciseDecimal::ONE,
132 NonFungibleLocalId::integer(1),
133 NonFungibleLocalId::bytes(vec![2, 3]).unwrap(),
134 );
135 let bytes = scrypto_encode(&values).unwrap();
136 assert_eq!(
137 bytes,
138 vec![
139 92, 33, 4, 160, 0, 0, 100, 167, 179, 182, 224, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143 0, 0, 176, 0, 0, 0, 0, 16, 159, 75, 179, 21, 7, 201, 123, 206, 151, 192, 0, 0, 0, 0, 0,
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 0, 1, 192, 2, 2, 2, 3 ]
149 );
150 assert_eq!(
151 scrypto_decode::<ScryptoValue>(&bytes).unwrap(),
152 ScryptoValue::Tuple {
153 fields: vec![
154 ScryptoValue::Custom {
155 value: ScryptoCustomValue::Decimal(Decimal::ONE),
156 },
157 ScryptoValue::Custom {
158 value: ScryptoCustomValue::PreciseDecimal(PreciseDecimal::ONE),
159 },
160 ScryptoValue::Custom {
161 value: ScryptoCustomValue::NonFungibleLocalId(NonFungibleLocalId::integer(
162 1
163 )),
164 },
165 ScryptoValue::Custom {
166 value: ScryptoCustomValue::NonFungibleLocalId(
167 NonFungibleLocalId::bytes(vec![2, 3]).unwrap()
168 ),
169 },
170 ]
171 }
172 );
173 }
174}