use crate::{
buffer::Payload,
ids::{ActorId, MessageId},
message::{
ContextStore, DispatchKind, GasLimit, StoredDispatch, StoredMessage, Value,
common::MessageDetails,
},
};
use alloc::sync::Arc;
use core::ops::Deref;
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(any(feature = "mock", test), derive(Default))]
pub struct IncomingMessage {
id: MessageId,
source: ActorId,
payload: Arc<Payload>,
gas_limit: GasLimit,
value: Value,
details: Option<MessageDetails>,
}
impl IncomingMessage {
pub fn new(
id: MessageId,
source: ActorId,
payload: Payload,
gas_limit: GasLimit,
value: Value,
details: Option<MessageDetails>,
) -> Self {
Self {
id,
source,
gas_limit,
value,
details,
payload: Arc::new(payload),
}
}
pub fn into_stored(self, destination: ActorId) -> StoredMessage {
StoredMessage::new(
self.id,
self.source,
destination,
Arc::try_unwrap(self.payload).unwrap_or_else(|payload| {
log::error!(
"IncomingMessage payload has multiple references, this is unexpected behavior"
);
Arc::unwrap_or_clone(payload)
}),
self.value,
self.details,
)
}
pub fn payload(&self) -> Arc<Payload> {
self.payload.clone()
}
pub fn id(&self) -> MessageId {
self.id
}
pub fn source(&self) -> ActorId {
self.source
}
pub fn gas_limit(&self) -> GasLimit {
self.gas_limit
}
pub fn value(&self) -> Value {
self.value
}
pub fn details(&self) -> Option<MessageDetails> {
self.details
}
pub fn is_error_reply(&self) -> bool {
self.details.map(|d| d.is_error_reply()).unwrap_or(false)
}
pub fn is_reply(&self) -> bool {
self.details.map(|d| d.is_reply_details()).unwrap_or(false)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(any(feature = "mock", test), derive(Default))]
pub struct IncomingDispatch {
kind: DispatchKind,
message: IncomingMessage,
context: Option<ContextStore>,
}
impl From<IncomingDispatch> for (DispatchKind, IncomingMessage, Option<ContextStore>) {
fn from(dispatch: IncomingDispatch) -> (DispatchKind, IncomingMessage, Option<ContextStore>) {
(dispatch.kind, dispatch.message, dispatch.context)
}
}
impl IncomingDispatch {
pub fn new(
kind: DispatchKind,
message: IncomingMessage,
context: Option<ContextStore>,
) -> Self {
Self {
kind,
message,
context,
}
}
pub fn into_stored(self, destination: ActorId, context: ContextStore) -> StoredDispatch {
StoredDispatch::new(
self.kind,
self.message.into_stored(destination),
Some(context),
)
}
pub fn into_parts(self) -> (DispatchKind, IncomingMessage, Option<ContextStore>) {
self.into()
}
pub fn kind(&self) -> DispatchKind {
self.kind
}
pub fn message(&self) -> &IncomingMessage {
&self.message
}
pub fn context(&self) -> &Option<ContextStore> {
&self.context
}
pub fn context_mut(&mut self) -> &mut Option<ContextStore> {
&mut self.context
}
}
impl Deref for IncomingDispatch {
type Target = IncomingMessage;
fn deref(&self) -> &Self::Target {
self.message()
}
}