#[cfg(test)]
use crate::core::{AccountBlockHandle, AccountCurrencies, BlockedAccounts};
use crate::core::{AccountGroups, AccountGroupsHandle, Accounts, GroupLookup};
use crate::param::{AccountGroupId, AccountId, Asset};
use crate::storage::{self, StorageBuilder};
pub struct PostTradeContext<StorageFactory>
where
StorageFactory: storage::LockingPolicyFactory + storage::CreateStorageFor<AccountId> + 'static,
{
accounts: Option<Accounts<StorageFactory>>,
account: Option<AccountId>,
group_lookup: GroupLookup<StorageFactory>,
}
impl<StorageFactory> PostTradeContext<StorageFactory>
where
StorageFactory: storage::LockingPolicyFactory + storage::CreateStorageFor<AccountId> + 'static,
{
pub(crate) fn with_groups(
account_groups: AccountGroupsHandle<StorageFactory>,
account: Option<AccountId>,
) -> Self {
Self {
accounts: None,
account,
group_lookup: GroupLookup::new(account_groups, account),
}
}
pub(crate) fn with_accounts(
accounts: Accounts<StorageFactory>,
account_groups: AccountGroupsHandle<StorageFactory>,
account: Option<AccountId>,
) -> Self {
Self {
accounts: Some(accounts),
account,
group_lookup: GroupLookup::new(account_groups, account),
}
}
pub fn new() -> Self
where
StorageFactory: Default,
{
let builder = StorageBuilder::new(StorageFactory::default());
let handle = AccountGroupsHandle::from_inner(StorageFactory::new_shared(
AccountGroups::new(&builder),
));
Self::with_groups(handle, None)
}
#[cfg(test)]
pub(crate) fn with_account_currency(account: AccountId, currency: Asset) -> Self
where
StorageFactory: Default + storage::CreateStorageFor<AccountGroupId>,
{
let builder = StorageBuilder::new(StorageFactory::default());
let account_groups = AccountGroupsHandle::from_inner(StorageFactory::new_shared(
AccountGroups::new(&builder),
));
let block_handle = AccountBlockHandle::from_inner(StorageFactory::new_shared(
BlockedAccounts::new(&builder),
));
let currencies = StorageFactory::new_shared(AccountCurrencies::new(&builder));
let config_registry = StorageFactory::new_shared(crate::core::ConfigRegistry::empty());
let accounts = Accounts::new(
account_groups.clone(),
block_handle,
currencies,
config_registry,
);
accounts.set_currency(account, currency);
Self::with_accounts(accounts, account_groups, Some(account))
}
pub fn account_group(&self) -> Option<AccountGroupId> {
self.group_lookup.group()
}
pub(crate) fn state_account_group(&self) -> Option<AccountGroupId> {
match (self.accounts.as_ref(), self.account) {
(Some(accounts), Some(account)) => accounts.group_of(account),
_ => self.group_lookup.group(),
}
}
pub(crate) fn account_currency(&self, account_group: Option<AccountGroupId>) -> Option<Asset> {
self.account.and_then(|account| {
self.accounts
.as_ref()?
.currency_of_in_group(account, account_group)
})
}
pub(crate) fn with_state_writer<R>(&self, operation: impl FnOnce() -> R) -> R {
match (self.accounts.as_ref(), self.account) {
(Some(accounts), Some(_)) => accounts.with_state_writer(operation),
_ => operation(),
}
}
}
impl<StorageFactory> Default for PostTradeContext<StorageFactory>
where
StorageFactory:
storage::LockingPolicyFactory + storage::CreateStorageFor<AccountId> + Default + 'static,
{
fn default() -> Self {
Self::new()
}
}
impl<StorageFactory> crate::marketdata::AccountInfo for PostTradeContext<StorageFactory>
where
StorageFactory: storage::LockingPolicyFactory + storage::CreateStorageFor<AccountId> + 'static,
{
fn group(&self) -> Option<AccountGroupId> {
self.account_group()
}
}