1mod abi_decoder;
2mod abi_encoder;
3mod abi_formatter;
4mod function_selector;
5mod logs;
6mod utils;
7
8use std::io::Read;
9
10pub use abi_decoder::*;
11pub use abi_encoder::*;
12pub use abi_formatter::*;
13pub use function_selector::*;
14pub use logs::*;
15
16use crate::{
17 traits::{Parameterize, Tokenizable},
18 types::errors::Result,
19};
20
21pub fn try_from_bytes<T>(bytes: impl Read, decoder_config: DecoderConfig) -> Result<T>
23where
24 T: Parameterize + Tokenizable,
25{
26 let token = ABIDecoder::new(decoder_config).decode(&T::param_type(), bytes)?;
27
28 T::from_token(token)
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::{
35 constants::WORD_SIZE,
36 types::{Address, AsciiString, AssetId, ContractId},
37 };
38
39 #[test]
40 fn convert_all_from_bool_to_u64() -> Result<()> {
41 let bytes = [255; WORD_SIZE];
42
43 macro_rules! test_decode {
44 ($($for_type: ident),*) => {
45 $(assert_eq!(
46 try_from_bytes::<$for_type>(bytes.as_slice(), DecoderConfig::default())?,
47 $for_type::MAX
48 );)*
49 };
50 }
51
52 assert!(try_from_bytes::<bool>(
53 bytes.as_slice(),
54 DecoderConfig::default()
55 )?);
56
57 test_decode!(u8, u16, u32, u64);
58
59 Ok(())
60 }
61
62 #[test]
63 fn convert_bytes_into_tuple() -> Result<()> {
64 let tuple_in_bytes = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2];
65
66 let the_tuple: (u64, u32) =
67 try_from_bytes(tuple_in_bytes.as_slice(), DecoderConfig::default())?;
68
69 assert_eq!(the_tuple, (1, 2));
70
71 Ok(())
72 }
73
74 #[test]
75 fn convert_native_types() -> Result<()> {
76 let bytes = [255; 32];
77
78 macro_rules! test_decode {
79 ($($for_type: ident),*) => {
80 $(assert_eq!(
81 try_from_bytes::<$for_type>(bytes.as_slice(), DecoderConfig::default())?,
82 $for_type::new(bytes.as_slice().try_into()?)
83 );)*
84 };
85 }
86
87 test_decode!(Address, ContractId, AssetId);
88
89 Ok(())
90 }
91
92 #[test]
93 fn string_slice_is_read_in_total() {
94 #[derive(
99 fuels_macros::Tokenizable, fuels_macros::Parameterize, Clone, PartialEq, Debug,
100 )]
101 #[FuelsCorePath = "crate"]
102 #[FuelsTypesPath = "crate::types"]
103 struct Test {
104 name: AsciiString,
105 age: u64,
106 }
107
108 let input = Test {
109 name: AsciiString::new("Alice".to_owned()).unwrap(),
110 age: 42,
111 };
112
113 let encoded = ABIEncoder::default()
114 .encode(&[input.clone().into_token()])
115 .unwrap();
116
117 let decoded = try_from_bytes::<Test>(encoded.as_slice(), DecoderConfig::default()).unwrap();
119
120 assert_eq!(decoded, input);
122 }
123}