use std::any::Any;
use crate::{
core::{
evaluationresults::EvaluationResults,
marketdatahandling::marketdata::{MarketDataProvider, MarketDataRequest},
pricingcontext::PricingContext,
request::Request,
},
utils::errors::{QSError, Result},
};
pub trait Pricer: Send + Sync {
type Item;
type Policy: ?Sized + Send + Sync;
fn evaluate(
&self,
trade: &Self::Item,
requests: &[Request],
ctx: &impl MarketDataProvider,
) -> Result<EvaluationResults>;
fn market_data_request(&self, trade: &Self::Item) -> Option<MarketDataRequest>;
fn set_discount_policy(&mut self, _policy: Box<Self::Policy>);
fn discount_policy(&self) -> Option<&Self::Policy>;
}
pub trait ErasedPricer: Send + Sync {
fn evaluate_erased(
&self,
trade: &dyn Any,
requests: &[Request],
ctx: &PricingContext,
) -> Result<EvaluationResults>;
}
impl<P> ErasedPricer for P
where
P: Pricer,
P::Item: Any,
{
fn evaluate_erased(
&self,
trade: &dyn Any,
requests: &[Request],
ctx: &PricingContext,
) -> Result<EvaluationResults> {
let typed_trade = trade.downcast_ref::<P::Item>().ok_or_else(|| {
QSError::InvalidValueErr(format!(
"Pricer expected a trade of type `{}`, but received a value with type id {:?}",
std::any::type_name::<P::Item>(),
trade.type_id()
))
})?;
self.evaluate(typed_trade, requests, ctx)
}
}