use super::OrderOutcome;
use crate::utils::write_indented;
use std::fmt;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CommandEffects {
target_order: OrderOutcome,
triggered_orders: Vec<OrderOutcome>,
}
impl CommandEffects {
pub(crate) fn new(target_order: OrderOutcome, triggered_orders: Vec<OrderOutcome>) -> Self {
Self {
target_order,
triggered_orders,
}
}
pub fn target_order(&self) -> &OrderOutcome {
&self.target_order
}
pub fn triggered_orders(&self) -> &[OrderOutcome] {
&self.triggered_orders
}
}
impl fmt::Display for CommandEffects {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "effects:")?;
write_indented(f, &format!("target {}", self.target_order()), 2)?;
for triggered_order in self.triggered_orders() {
write_indented(f, &format!("triggered {}", triggered_order), 2)?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{CancelReason, MatchResult, OrderId, OrderOutcome, Side};
#[test]
fn test_display() {
let command_effects = CommandEffects::new(OrderOutcome::new(OrderId(1)), Vec::new());
println!("{}", command_effects);
assert_eq!(
command_effects.to_string(),
"effects:\n target order(1):\n not matched\n not cancelled\n"
);
let command_effects = CommandEffects::new(
OrderOutcome::new(OrderId(1)),
vec![OrderOutcome::new(OrderId(2))],
);
println!("{}", command_effects);
assert_eq!(
command_effects.to_string(),
"effects:\n target order(1):\n not matched\n not cancelled\n triggered order(2):\n not matched\n not cancelled\n"
);
let command_effects = CommandEffects::new(
OrderOutcome::new(OrderId(1)),
vec![OrderOutcome::new(OrderId(2)), OrderOutcome::new(OrderId(3))],
);
println!("{}", command_effects);
assert_eq!(
command_effects.to_string(),
"effects:\n target order(1):\n not matched\n not cancelled\n triggered order(2):\n not matched\n not cancelled\n triggered order(3):\n not matched\n not cancelled\n"
);
let mut order_outcome = OrderOutcome::new(OrderId(1));
order_outcome.set_match_result(MatchResult::new(Side::Buy));
let command_effects = CommandEffects::new(
order_outcome,
vec![OrderOutcome::new(OrderId(2)), OrderOutcome::new(OrderId(3))],
);
println!("{}", command_effects);
assert_eq!(
command_effects.to_string(),
"effects:\n target order(1):\n matched: taker_side=BUY executed_quantity=0 executed_value=0 trades=0\n not cancelled\n triggered order(2):\n not matched\n not cancelled\n triggered order(3):\n not matched\n not cancelled\n"
);
let mut order_outcome = OrderOutcome::new(OrderId(1));
order_outcome.set_match_result(MatchResult::new(Side::Buy));
let mut order_outcome2 = OrderOutcome::new(OrderId(2));
order_outcome2.set_match_result(MatchResult::new(Side::Buy));
let mut order_outcome3 = OrderOutcome::new(OrderId(3));
order_outcome3.set_cancel_reason(CancelReason::PostOnlyWouldTake);
let command_effects =
CommandEffects::new(order_outcome, vec![order_outcome2, order_outcome3]);
println!("{}", command_effects);
assert_eq!(
command_effects.to_string(),
"effects:\n target order(1):\n matched: taker_side=BUY executed_quantity=0 executed_value=0 trades=0\n not cancelled\n triggered order(2):\n matched: taker_side=BUY executed_quantity=0 executed_value=0 trades=0\n not cancelled\n triggered order(3):\n not matched\n cancelled: post-only order would remove liquidity\n"
);
}
}