use crate::bond::{Bond, BondEngine, BondOutcome};
use crate::error::Result;
use crate::intent::Intent;
use crate::policy::{RoutePolicy, Solution};
use crate::route::Fill;
use crate::venue::VenueExecutor;
pub struct ScemaDex<P, B, V> {
pub policy: P,
pub bond: B,
pub venue: V,
}
impl<P, B, V> ScemaDex<P, B, V>
where
P: RoutePolicy,
B: BondEngine,
V: VenueExecutor,
{
pub fn new(policy: P, bond: B, venue: V) -> Self {
Self { policy, bond, venue }
}
pub async fn quote(&self, intent: &Intent) -> Result<(Solution, Bond)> {
let solution = self.policy.solve(intent).await?;
let bond = self.bond.escrow(&solution).await?;
Ok((solution, bond))
}
pub async fn execute(&self, intent: &Intent) -> Result<(Fill, BondOutcome)> {
let (solution, bond) = self.quote(intent).await?;
let fill = self.venue.execute(&solution.route).await?;
let outcome = self.bond.settle(&bond, &fill).await?;
Ok((fill, outcome))
}
}