fuel_core_storage/codec/
primitive.rs1use crate::codec::{
7 Decode,
8 Encode,
9};
10use fuel_core_types::{
11 blockchain::primitives::DaBlockHeight,
12 fuel_tx::{
13 TxId,
14 UtxoId,
15 },
16 fuel_types::BlockHeight,
17};
18
19pub struct Primitive<const SIZE: usize>;
22
23macro_rules! impl_encode {
24 ($($ty:ty, $size:expr_2021),*) => {
25 $(
26 impl Encode<$ty> for Primitive<{ $size }> {
27 type Encoder<'a> = [u8; { $size }];
28
29 fn encode(t: &$ty) -> Self::Encoder<'_> {
30 t.to_be_bytes()
31 }
32 }
33 )*
34 };
35}
36macro_rules! impl_decode {
37 ($($ty:ty, $size:expr_2021),*) => {
38 $(
39 impl Decode<$ty> for Primitive<{ $size }> {
40 fn decode(bytes: &[u8]) -> anyhow::Result<$ty> {
41 Ok(<$ty>::from_be_bytes(<[u8; { $size }]>::try_from(bytes)?))
42 }
43 }
44 )*
45 };
46}
47
48impl_encode! {
49 u8, 1,
50 u16, 2,
51 u32, 4,
52 BlockHeight, 4,
53 DaBlockHeight, 8,
54 u64, 8,
55 u128, 16
56}
57
58impl_decode! {
59 u8, 1,
60 u16, 2,
61 u32, 4,
62 u64, 8,
63 u128, 16
64}
65
66impl Decode<BlockHeight> for Primitive<4> {
67 fn decode(bytes: &[u8]) -> anyhow::Result<BlockHeight> {
68 Ok(BlockHeight::from(<[u8; 4]>::try_from(bytes)?))
69 }
70}
71
72impl Decode<DaBlockHeight> for Primitive<8> {
73 fn decode(bytes: &[u8]) -> anyhow::Result<DaBlockHeight> {
74 Ok(DaBlockHeight::from(<[u8; 8]>::try_from(bytes)?))
75 }
76}
77
78pub fn utxo_id_to_bytes(utxo_id: &UtxoId) -> [u8; TxId::LEN + 2] {
80 let mut default = [0; TxId::LEN + 2];
81 default[0..TxId::LEN].copy_from_slice(utxo_id.tx_id().as_ref());
82 default[TxId::LEN..].copy_from_slice(utxo_id.output_index().to_be_bytes().as_slice());
83 default
84}
85
86impl Encode<UtxoId> for Primitive<{ TxId::LEN + 2 }> {
87 type Encoder<'a> = [u8; TxId::LEN + 2];
88
89 fn encode(t: &UtxoId) -> Self::Encoder<'_> {
90 utxo_id_to_bytes(t)
91 }
92}
93
94impl Decode<UtxoId> for Primitive<{ TxId::LEN + 2 }> {
95 fn decode(bytes: &[u8]) -> anyhow::Result<UtxoId> {
96 let bytes = <[u8; TxId::LEN + 2]>::try_from(bytes)?;
97 let tx_id: [u8; TxId::LEN] = bytes[0..TxId::LEN].try_into()?;
98 let output_index = u16::from_be_bytes(bytes[TxId::LEN..].try_into()?);
99 Ok(UtxoId::new(TxId::from(tx_id), output_index))
100 }
101}