use std::{cell::RefCell, rc::Rc};
use nautilus_common::{cache::Cache, msgbus::Handler};
use nautilus_model::{
defi::{PoolFeeCollect, PoolFlash, PoolLiquidityUpdate, PoolLiquidityUpdateType, PoolSwap},
identifiers::InstrumentId,
};
use ustr::Ustr;
#[derive(Debug)]
pub struct PoolUpdater {
id: Ustr,
instrument_id: InstrumentId,
cache: Rc<RefCell<Cache>>,
}
impl PoolUpdater {
#[must_use]
pub fn new(instrument_id: &InstrumentId, cache: Rc<RefCell<Cache>>) -> Self {
Self {
id: Ustr::from(&format!("{}-{}", stringify!(PoolUpdater), instrument_id)),
instrument_id: *instrument_id,
cache,
}
}
#[must_use]
pub fn id(&self) -> Ustr {
self.id
}
pub fn handle_pool_swap(&self, swap: &PoolSwap) {
if let Some(pool_profiler) = self
.cache
.borrow_mut()
.pool_profiler_mut(&self.instrument_id)
&& let Err(e) = pool_profiler.process_swap(swap)
{
log::error!("Failed to process pool swap: {e}");
}
}
pub fn handle_pool_liquidity_update(&self, update: &PoolLiquidityUpdate) {
if let Some(pool_profiler) = self
.cache
.borrow_mut()
.pool_profiler_mut(&self.instrument_id)
&& let Err(e) = match update.kind {
PoolLiquidityUpdateType::Mint => pool_profiler.process_mint(update),
PoolLiquidityUpdateType::Burn => pool_profiler.process_burn(update),
_ => panic!("Liquidity update operation {} not implemented", update.kind),
}
{
log::error!("Failed to process pool liquidity update: {e}");
}
}
pub fn handle_pool_fee_collect(&self, event: &PoolFeeCollect) {
if let Some(pool_profiler) = self
.cache
.borrow_mut()
.pool_profiler_mut(&self.instrument_id)
&& let Err(e) = pool_profiler.process_collect(event)
{
log::error!("Failed to process pool fee collect: {e}");
}
}
pub fn handle_pool_flash(&self, event: &PoolFlash) {
if let Some(pool_profiler) = self
.cache
.borrow_mut()
.pool_profiler_mut(&self.instrument_id)
&& let Err(e) = pool_profiler.process_flash(event)
{
log::error!("Failed to process pool flash: {e}");
}
}
}
#[derive(Debug)]
pub struct PoolSwapHandler {
id: Ustr,
updater: Rc<PoolUpdater>,
}
impl PoolSwapHandler {
#[must_use]
pub fn new(updater: Rc<PoolUpdater>) -> Self {
Self {
id: Ustr::from(&format!("PoolSwapHandler-{}", updater.id())),
updater,
}
}
}
impl Handler<PoolSwap> for PoolSwapHandler {
fn id(&self) -> Ustr {
self.id
}
fn handle(&self, msg: &PoolSwap) {
self.updater.handle_pool_swap(msg);
}
}
#[derive(Debug)]
pub struct PoolLiquidityHandler {
id: Ustr,
updater: Rc<PoolUpdater>,
}
impl PoolLiquidityHandler {
#[must_use]
pub fn new(updater: Rc<PoolUpdater>) -> Self {
Self {
id: Ustr::from(&format!("PoolLiquidityHandler-{}", updater.id())),
updater,
}
}
}
impl Handler<PoolLiquidityUpdate> for PoolLiquidityHandler {
fn id(&self) -> Ustr {
self.id
}
fn handle(&self, msg: &PoolLiquidityUpdate) {
self.updater.handle_pool_liquidity_update(msg);
}
}
#[derive(Debug)]
pub struct PoolCollectHandler {
id: Ustr,
updater: Rc<PoolUpdater>,
}
impl PoolCollectHandler {
#[must_use]
pub fn new(updater: Rc<PoolUpdater>) -> Self {
Self {
id: Ustr::from(&format!("PoolCollectHandler-{}", updater.id())),
updater,
}
}
}
impl Handler<PoolFeeCollect> for PoolCollectHandler {
fn id(&self) -> Ustr {
self.id
}
fn handle(&self, msg: &PoolFeeCollect) {
self.updater.handle_pool_fee_collect(msg);
}
}
#[derive(Debug)]
pub struct PoolFlashHandler {
id: Ustr,
updater: Rc<PoolUpdater>,
}
impl PoolFlashHandler {
#[must_use]
pub fn new(updater: Rc<PoolUpdater>) -> Self {
Self {
id: Ustr::from(&format!("PoolFlashHandler-{}", updater.id())),
updater,
}
}
}
impl Handler<PoolFlash> for PoolFlashHandler {
fn id(&self) -> Ustr {
self.id
}
fn handle(&self, msg: &PoolFlash) {
self.updater.handle_pool_flash(msg);
}
}