use crate::{
constants::BlockNumber,
state::{WithOverlay, blocks::GetBlockNumberImpl},
};
use gear_common::storage::{
AuxiliaryDoubleStorageWrap, DoubleBTreeMap, Interval, IterableByKeyMap, Mailbox,
MailboxCallbacks, MailboxError, MailboxImpl, MailboxKeyGen,
};
use gear_core::{
ids::{ActorId, MessageId},
message::UserStoredMessage,
};
use std::thread::LocalKey;
type AuxiliaryMailbox = MailboxImpl<
MailboxStorageWrap,
MailboxedMessage,
BlockNumber,
MailboxErrorImpl,
MailboxErrorImpl,
MailboxCallbacksImpl,
MailboxKeyGen<ActorId>,
>;
pub(crate) type MailboxedMessage = UserStoredMessage;
type MailboxStorage =
WithOverlay<DoubleBTreeMap<ActorId, MessageId, (MailboxedMessage, Interval<BlockNumber>)>>;
std::thread_local! {
pub(super) static MAILBOX_STORAGE: MailboxStorage = Default::default();
}
fn storage() -> &'static LocalKey<MailboxStorage> {
&MAILBOX_STORAGE
}
#[derive(Debug, Default)]
pub(crate) struct MailboxManager;
impl MailboxManager {
pub(crate) fn insert(
&self,
message: MailboxedMessage,
expected: BlockNumber,
) -> Result<(), MailboxErrorImpl> {
<AuxiliaryMailbox as Mailbox>::insert(message, expected)
}
pub(crate) fn remove(
&self,
user: ActorId,
reply_to: MessageId,
) -> Result<(MailboxedMessage, Interval<BlockNumber>), MailboxErrorImpl> {
<AuxiliaryMailbox as Mailbox>::remove(user, reply_to)
}
pub(crate) fn iter_key(
&self,
to: ActorId,
) -> impl Iterator<Item = (MailboxedMessage, Interval<BlockNumber>)> + use<> {
<AuxiliaryMailbox as IterableByKeyMap<_>>::iter_key(to)
}
pub(crate) fn clear(&self) {
<AuxiliaryMailbox as Mailbox>::clear();
}
}
struct MailboxCallbacksImpl;
impl MailboxCallbacks<MailboxErrorImpl> for MailboxCallbacksImpl {
type Value = MailboxedMessage;
type BlockNumber = BlockNumber;
type GetBlockNumber = GetBlockNumberImpl;
type OnInsert = ();
type OnRemove = ();
}
pub struct MailboxStorageWrap;
impl AuxiliaryDoubleStorageWrap for MailboxStorageWrap {
type Key1 = ActorId;
type Key2 = MessageId;
type Value = (MailboxedMessage, Interval<BlockNumber>);
fn with_storage<F, R>(f: F) -> R
where
F: FnOnce(&DoubleBTreeMap<Self::Key1, Self::Key2, Self::Value>) -> R,
{
storage().with(|ms| f(&ms.data()))
}
fn with_storage_mut<F, R>(f: F) -> R
where
F: FnOnce(&mut DoubleBTreeMap<Self::Key1, Self::Key2, Self::Value>) -> R,
{
storage().with(|ms| f(&mut ms.data_mut()))
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum MailboxErrorImpl {
DuplicateKey,
ElementNotFound,
}
impl MailboxError for MailboxErrorImpl {
fn duplicate_key() -> Self {
Self::DuplicateKey
}
fn element_not_found() -> Self {
Self::ElementNotFound
}
}