1use crate::{
20 buffer::Payload,
21 ids::{ActorId, MessageId},
22 message::{
23 DispatchKind, GasLimit, StoredDelayedDispatch, StoredDispatch, StoredMessage, Value,
24 },
25};
26use core::ops::Deref;
27use gear_core_errors::{ReplyCode, SignalCode};
28use parity_scale_codec::{Decode, Encode};
29use scale_decode::DecodeAsType;
30use scale_encode::EncodeAsType;
31use scale_info::TypeInfo;
32
33#[derive(Clone, Debug, PartialEq, Eq, Decode, DecodeAsType, Encode, EncodeAsType)]
36pub struct Message {
37 id: MessageId,
39 source: ActorId,
41 destination: ActorId,
43 payload: Payload,
45 gas_limit: Option<GasLimit>,
47 value: Value,
49 details: Option<MessageDetails>,
51}
52
53impl From<Message> for StoredMessage {
54 fn from(message: Message) -> StoredMessage {
55 StoredMessage::new(
56 message.id,
57 message.source,
58 message.destination,
59 message.payload,
60 message.value,
61 message.details,
62 )
63 }
64}
65
66impl Message {
67 pub fn new(
69 id: MessageId,
70 source: ActorId,
71 destination: ActorId,
72 payload: Payload,
73 gas_limit: Option<GasLimit>,
74 value: Value,
75 details: Option<MessageDetails>,
76 ) -> Self {
77 Self {
78 id,
79 source,
80 destination,
81 payload,
82 gas_limit,
83 value,
84 details,
85 }
86 }
87
88 pub fn into_parts(
90 self,
91 ) -> (
92 MessageId,
93 ActorId,
94 ActorId,
95 Payload,
96 Option<GasLimit>,
97 Value,
98 Option<MessageDetails>,
99 ) {
100 (
101 self.id,
102 self.source,
103 self.destination,
104 self.payload,
105 self.gas_limit,
106 self.value,
107 self.details,
108 )
109 }
110
111 pub fn into_stored(self) -> StoredMessage {
113 self.into()
114 }
115
116 pub fn id(&self) -> MessageId {
118 self.id
119 }
120
121 pub fn source(&self) -> ActorId {
123 self.source
124 }
125
126 pub fn destination(&self) -> ActorId {
128 self.destination
129 }
130
131 pub fn payload_bytes(&self) -> &[u8] {
133 &self.payload
134 }
135
136 pub fn gas_limit(&self) -> Option<GasLimit> {
138 self.gas_limit
139 }
140
141 pub fn value(&self) -> Value {
143 self.value
144 }
145
146 pub fn reply_details(&self) -> Option<ReplyDetails> {
148 self.details.and_then(|d| d.to_reply_details())
149 }
150
151 pub fn signal_details(&self) -> Option<SignalDetails> {
153 self.details.and_then(|d| d.to_signal_details())
154 }
155
156 pub fn is_error_reply(&self) -> bool {
158 self.details.map(|d| d.is_error_reply()).unwrap_or(false)
159 }
160
161 pub fn is_reply(&self) -> bool {
163 self.reply_details().is_some()
164 }
165}
166
167#[derive(
169 Clone,
170 Copy,
171 Debug,
172 PartialEq,
173 Eq,
174 Hash,
175 Decode,
176 DecodeAsType,
177 Encode,
178 EncodeAsType,
179 TypeInfo,
180 derive_more::From,
181)]
182#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
183pub enum MessageDetails {
184 Reply(ReplyDetails),
186 Signal(SignalDetails),
188}
189
190impl MessageDetails {
191 pub fn is_error_reply(&self) -> bool {
193 self.to_reply_details()
194 .map(|d| d.code.is_error())
195 .unwrap_or(false)
196 }
197
198 pub fn is_reply_details(&self) -> bool {
200 matches!(self, Self::Reply(_))
201 }
202
203 pub fn to_reply_details(self) -> Option<ReplyDetails> {
205 match self {
206 MessageDetails::Reply(reply) => Some(reply),
207 MessageDetails::Signal(_) => None,
208 }
209 }
210
211 pub fn is_signal_details(&self) -> bool {
213 matches!(self, Self::Signal(_))
214 }
215
216 pub fn to_signal_details(self) -> Option<SignalDetails> {
218 match self {
219 MessageDetails::Reply(_) => None,
220 MessageDetails::Signal(signal) => Some(signal),
221 }
222 }
223}
224
225#[derive(
230 Clone, Copy, Debug, PartialEq, Eq, Hash, Decode, DecodeAsType, Encode, EncodeAsType, TypeInfo,
231)]
232#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
233pub struct ReplyDetails {
234 to: MessageId,
236 code: ReplyCode,
238}
239
240impl ReplyDetails {
241 pub fn new(to: MessageId, code: ReplyCode) -> Self {
243 Self { to, code }
244 }
245
246 pub fn to_message_id(&self) -> MessageId {
248 self.to
249 }
250
251 pub fn to_reply_code(&self) -> ReplyCode {
253 self.code
254 }
255
256 pub fn into_parts(self) -> (MessageId, ReplyCode) {
258 (self.to, self.code)
259 }
260}
261
262#[derive(
264 Clone, Copy, Debug, PartialEq, Eq, Hash, Decode, DecodeAsType, Encode, EncodeAsType, TypeInfo,
265)]
266#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
267pub struct SignalDetails {
268 to: MessageId,
270 code: SignalCode,
272}
273
274impl SignalDetails {
275 pub fn new(to: MessageId, code: SignalCode) -> Self {
277 Self { to, code }
278 }
279
280 pub fn to_message_id(&self) -> MessageId {
282 self.to
283 }
284
285 pub fn to_signal_code(&self) -> SignalCode {
287 self.code
288 }
289
290 pub fn into_parts(self) -> (MessageId, SignalCode) {
292 (self.to, self.code)
293 }
294}
295
296#[derive(Clone, Debug, PartialEq, Eq, Decode, DecodeAsType, Encode, EncodeAsType)]
298pub struct Dispatch {
299 kind: DispatchKind,
301 message: Message,
303}
304
305impl From<Dispatch> for StoredDispatch {
306 fn from(dispatch: Dispatch) -> StoredDispatch {
307 StoredDispatch::new(dispatch.kind, dispatch.message.into(), None)
308 }
309}
310
311impl From<Dispatch> for StoredDelayedDispatch {
312 fn from(dispatch: Dispatch) -> StoredDelayedDispatch {
313 StoredDelayedDispatch::new(dispatch.kind, dispatch.message.into())
314 }
315}
316
317impl From<Dispatch> for (DispatchKind, Message) {
318 fn from(dispatch: Dispatch) -> (DispatchKind, Message) {
319 (dispatch.kind, dispatch.message)
320 }
321}
322
323impl Dispatch {
324 pub fn new(kind: DispatchKind, message: Message) -> Self {
326 Self { kind, message }
327 }
328
329 pub fn into_stored(self) -> StoredDispatch {
331 self.into()
332 }
333
334 pub fn into_stored_delayed(self) -> StoredDelayedDispatch {
336 self.into()
337 }
338
339 pub fn into_parts(self) -> (DispatchKind, Message) {
341 self.into()
342 }
343
344 pub fn kind(&self) -> DispatchKind {
346 self.kind
347 }
348
349 pub fn message(&self) -> &Message {
351 &self.message
352 }
353}
354
355impl Deref for Dispatch {
356 type Target = Message;
357
358 fn deref(&self) -> &Self::Target {
359 self.message()
360 }
361}