1use crate::{
5 buffer::Payload,
6 ids::{ActorId, MessageId},
7 message::{
8 DispatchKind, GasLimit, StoredDelayedDispatch, StoredDispatch, StoredMessage, Value,
9 },
10};
11use core::ops::Deref;
12use gear_core_errors::{ReplyCode, SignalCode};
13use parity_scale_codec::{Decode, Encode};
14use scale_decode::DecodeAsType;
15use scale_encode::EncodeAsType;
16use scale_info::TypeInfo;
17
18#[derive(Clone, Debug, PartialEq, Eq, Decode, DecodeAsType, Encode, EncodeAsType)]
21pub struct Message {
22 id: MessageId,
24 source: ActorId,
26 destination: ActorId,
28 payload: Payload,
30 gas_limit: Option<GasLimit>,
32 value: Value,
34 details: Option<MessageDetails>,
36}
37
38impl From<Message> for StoredMessage {
39 fn from(message: Message) -> StoredMessage {
40 StoredMessage::new(
41 message.id,
42 message.source,
43 message.destination,
44 message.payload,
45 message.value,
46 message.details,
47 )
48 }
49}
50
51impl Message {
52 pub fn new(
54 id: MessageId,
55 source: ActorId,
56 destination: ActorId,
57 payload: Payload,
58 gas_limit: Option<GasLimit>,
59 value: Value,
60 details: Option<MessageDetails>,
61 ) -> Self {
62 Self {
63 id,
64 source,
65 destination,
66 payload,
67 gas_limit,
68 value,
69 details,
70 }
71 }
72
73 pub fn into_parts(
75 self,
76 ) -> (
77 MessageId,
78 ActorId,
79 ActorId,
80 Payload,
81 Option<GasLimit>,
82 Value,
83 Option<MessageDetails>,
84 ) {
85 (
86 self.id,
87 self.source,
88 self.destination,
89 self.payload,
90 self.gas_limit,
91 self.value,
92 self.details,
93 )
94 }
95
96 pub fn into_stored(self) -> StoredMessage {
98 self.into()
99 }
100
101 pub fn id(&self) -> MessageId {
103 self.id
104 }
105
106 pub fn source(&self) -> ActorId {
108 self.source
109 }
110
111 pub fn destination(&self) -> ActorId {
113 self.destination
114 }
115
116 pub fn payload_bytes(&self) -> &[u8] {
118 &self.payload
119 }
120
121 pub fn gas_limit(&self) -> Option<GasLimit> {
123 self.gas_limit
124 }
125
126 pub fn value(&self) -> Value {
128 self.value
129 }
130
131 pub fn reply_details(&self) -> Option<ReplyDetails> {
133 self.details.and_then(|d| d.to_reply_details())
134 }
135
136 pub fn signal_details(&self) -> Option<SignalDetails> {
138 self.details.and_then(|d| d.to_signal_details())
139 }
140
141 pub fn is_error_reply(&self) -> bool {
143 self.details.map(|d| d.is_error_reply()).unwrap_or(false)
144 }
145
146 pub fn is_reply(&self) -> bool {
148 self.reply_details().is_some()
149 }
150}
151
152#[derive(
154 Clone,
155 Copy,
156 Debug,
157 PartialEq,
158 Eq,
159 Hash,
160 Decode,
161 DecodeAsType,
162 Encode,
163 EncodeAsType,
164 TypeInfo,
165 derive_more::From,
166)]
167#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
168pub enum MessageDetails {
169 Reply(ReplyDetails),
171 Signal(SignalDetails),
173}
174
175impl MessageDetails {
176 pub fn is_error_reply(&self) -> bool {
178 self.to_reply_details()
179 .map(|d| d.code.is_error())
180 .unwrap_or(false)
181 }
182
183 pub fn is_reply_details(&self) -> bool {
185 matches!(self, Self::Reply(_))
186 }
187
188 pub fn to_reply_details(self) -> Option<ReplyDetails> {
190 match self {
191 MessageDetails::Reply(reply) => Some(reply),
192 MessageDetails::Signal(_) => None,
193 }
194 }
195
196 pub fn is_signal_details(&self) -> bool {
198 matches!(self, Self::Signal(_))
199 }
200
201 pub fn to_signal_details(self) -> Option<SignalDetails> {
203 match self {
204 MessageDetails::Reply(_) => None,
205 MessageDetails::Signal(signal) => Some(signal),
206 }
207 }
208}
209
210#[derive(
215 Clone, Copy, Debug, PartialEq, Eq, Hash, Decode, DecodeAsType, Encode, EncodeAsType, TypeInfo,
216)]
217#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
218pub struct ReplyDetails {
219 to: MessageId,
221 code: ReplyCode,
223}
224
225impl ReplyDetails {
226 pub fn new(to: MessageId, code: ReplyCode) -> Self {
228 Self { to, code }
229 }
230
231 pub fn to_message_id(&self) -> MessageId {
233 self.to
234 }
235
236 pub fn to_reply_code(&self) -> ReplyCode {
238 self.code
239 }
240
241 pub fn into_parts(self) -> (MessageId, ReplyCode) {
243 (self.to, self.code)
244 }
245}
246
247#[derive(
249 Clone, Copy, Debug, PartialEq, Eq, Hash, Decode, DecodeAsType, Encode, EncodeAsType, TypeInfo,
250)]
251#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
252pub struct SignalDetails {
253 to: MessageId,
255 code: SignalCode,
257}
258
259impl SignalDetails {
260 pub fn new(to: MessageId, code: SignalCode) -> Self {
262 Self { to, code }
263 }
264
265 pub fn to_message_id(&self) -> MessageId {
267 self.to
268 }
269
270 pub fn to_signal_code(&self) -> SignalCode {
272 self.code
273 }
274
275 pub fn into_parts(self) -> (MessageId, SignalCode) {
277 (self.to, self.code)
278 }
279}
280
281#[derive(Clone, Debug, PartialEq, Eq, Decode, DecodeAsType, Encode, EncodeAsType)]
283pub struct Dispatch {
284 kind: DispatchKind,
286 message: Message,
288}
289
290impl From<Dispatch> for StoredDispatch {
291 fn from(dispatch: Dispatch) -> StoredDispatch {
292 StoredDispatch::new(dispatch.kind, dispatch.message.into(), None)
293 }
294}
295
296impl From<Dispatch> for StoredDelayedDispatch {
297 fn from(dispatch: Dispatch) -> StoredDelayedDispatch {
298 StoredDelayedDispatch::new(dispatch.kind, dispatch.message.into())
299 }
300}
301
302impl From<Dispatch> for (DispatchKind, Message) {
303 fn from(dispatch: Dispatch) -> (DispatchKind, Message) {
304 (dispatch.kind, dispatch.message)
305 }
306}
307
308impl Dispatch {
309 pub fn new(kind: DispatchKind, message: Message) -> Self {
311 Self { kind, message }
312 }
313
314 pub fn into_stored(self) -> StoredDispatch {
316 self.into()
317 }
318
319 pub fn into_stored_delayed(self) -> StoredDelayedDispatch {
321 self.into()
322 }
323
324 pub fn into_parts(self) -> (DispatchKind, Message) {
326 self.into()
327 }
328
329 pub fn kind(&self) -> DispatchKind {
331 self.kind
332 }
333
334 pub fn message(&self) -> &Message {
336 &self.message
337 }
338}
339
340impl Deref for Dispatch {
341 type Target = Message;
342
343 fn deref(&self) -> &Self::Target {
344 self.message()
345 }
346}