1use common_primitives::{
2 messages::MessageResponse,
3 msa::MessageSourceId,
4 node::BlockNumber,
5 schema::{PayloadLocation, SchemaId},
6};
7use core::fmt::Debug;
8use frame_support::{traits::Get, BoundedVec};
9use multibase::Base;
10use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
11use scale_info::TypeInfo;
12extern crate alloc;
13use alloc::vec::Vec;
14use common_primitives::messages::MessageResponseV2;
15
16pub type OffchainPayloadType = (Vec<u8>, u32);
18pub type MessageIndex = u16;
20
21#[derive(Default, Encode, Decode, PartialEq, Debug, TypeInfo, Eq, MaxEncodedLen)]
23#[scale_info(skip_type_params(MaxDataSize))]
24#[codec(mel_bound(MaxDataSize: MaxEncodedLen))]
25pub struct Message<MaxDataSize>
26where
27 MaxDataSize: Get<u32> + Debug,
28{
29 pub payload: BoundedVec<u8, MaxDataSize>,
31 pub provider_msa_id: MessageSourceId,
36 pub msa_id: Option<MessageSourceId>,
38 pub schema_id: SchemaId,
40}
41
42pub trait MapToResponse<I, R> {
44 fn map_to_response(&self, index_values: I) -> Option<R>;
46}
47
48impl<MaxDataSize: Get<u32> + Debug>
49 MapToResponse<(BlockNumber, PayloadLocation, u16), MessageResponse> for Message<MaxDataSize>
50{
51 fn map_to_response(
52 &self,
53 index_values: (BlockNumber, PayloadLocation, u16),
54 ) -> Option<MessageResponse> {
55 let (block_number, payload_location, index) = index_values;
56 let base_response = MessageResponse {
57 provider_msa_id: self.provider_msa_id,
58 index,
59 block_number,
60 msa_id: self.msa_id,
61 ..Default::default()
62 };
63
64 match payload_location {
65 PayloadLocation::OnChain => Some(MessageResponse {
66 payload: Some(self.payload.to_vec()),
67 cid: None,
68 payload_length: None,
69 ..base_response
70 }),
71 PayloadLocation::IPFS => {
72 let (binary_cid, payload_length) =
73 OffchainPayloadType::decode(&mut &self.payload[..]).unwrap_or_default();
74 Some(MessageResponse {
75 cid: Some(multibase::encode(Base::Base32Lower, binary_cid).as_bytes().to_vec()),
76 payload_length: Some(payload_length),
77 payload: None,
78 ..base_response
79 })
80 }, _ => None,
82 }
83 }
84}
85
86impl<MaxDataSize: Get<u32> + Debug>
87 MapToResponse<(BlockNumber, SchemaId, PayloadLocation, u16), MessageResponseV2>
88 for Message<MaxDataSize>
89{
90 fn map_to_response(
92 &self,
93 index_values: (BlockNumber, SchemaId, PayloadLocation, u16),
94 ) -> Option<MessageResponseV2> {
95 let (block_number, schema_id, payload_location, index) = index_values;
96 let base_response = MessageResponseV2 {
97 provider_msa_id: self.provider_msa_id,
98 index,
99 block_number,
100 msa_id: self.msa_id,
101 schema_id,
102 ..Default::default()
103 };
104
105 match payload_location {
106 PayloadLocation::OnChain => Some(MessageResponseV2 {
107 payload: Some(self.payload.to_vec()),
108 cid: None,
109 payload_length: None,
110 ..base_response
111 }),
112 PayloadLocation::IPFS => {
113 let (binary_cid, payload_length) =
114 OffchainPayloadType::decode(&mut &self.payload[..]).unwrap_or_default();
115 Some(MessageResponseV2 {
116 cid: Some(multibase::encode(Base::Base32Lower, binary_cid).as_bytes().to_vec()),
117 payload_length: Some(payload_length),
118 payload: None,
119 ..base_response
120 })
121 }, _ => None,
123 }
124 }
125}
126
127impl<MaxDataSize: Get<u32> + Debug>
128 MapToResponse<(BlockNumber, PayloadLocation, u16), MessageResponseV2> for Message<MaxDataSize>
129{
130 fn map_to_response(
132 &self,
133 index_values: (BlockNumber, PayloadLocation, u16),
134 ) -> Option<MessageResponseV2> {
135 let (block_number, payload_location, index) = index_values;
136 let base_response = MessageResponseV2 {
137 provider_msa_id: self.provider_msa_id,
138 index,
139 block_number,
140 msa_id: self.msa_id,
141 schema_id: self.schema_id,
142 ..Default::default()
143 };
144
145 match payload_location {
146 PayloadLocation::OnChain => Some(MessageResponseV2 {
147 payload: Some(self.payload.to_vec()),
148 cid: None,
149 payload_length: None,
150 ..base_response
151 }),
152 PayloadLocation::IPFS => {
153 let (binary_cid, payload_length) =
154 OffchainPayloadType::decode(&mut &self.payload[..]).unwrap_or_default();
155 Some(MessageResponseV2 {
156 cid: Some(multibase::encode(Base::Base32Lower, binary_cid).as_bytes().to_vec()),
157 payload_length: Some(payload_length),
158 payload: None,
159 ..base_response
160 })
161 }, _ => None,
163 }
164 }
165}