use crate::internal::domain::{ErrorCode, GatewayError, Money, Quantity, TimeInForce};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct OrderModifyFields {
pub quantity: Option<Quantity>,
pub limit_price: Option<Money>,
pub stop_price: Option<Money>,
pub time_in_force: Option<TimeInForce>,
pub trailing_amount: Option<Money>,
pub trailing_percent: Option<Decimal>,
}
impl OrderModifyFields {
#[must_use]
pub const fn has_changes(&self) -> bool {
self.quantity.is_some()
|| self.limit_price.is_some()
|| self.stop_price.is_some()
|| self.time_in_force.is_some()
|| self.trailing_amount.is_some()
|| self.trailing_percent.is_some()
}
pub fn validate(&self) -> Result<(), GatewayError> {
if self.stop_price.is_some()
&& (self.trailing_amount.is_some() || self.trailing_percent.is_some())
{
return Err(GatewayError::new(
ErrorCode::OrderValidationFailed,
"Order modify cannot combine stop price and trailing stop fields",
false,
Some("Choose either stop_price or trailing_amount/trailing_percent".to_string()),
));
}
if self.trailing_amount.is_some() && self.trailing_percent.is_some() {
return Err(GatewayError::new(
ErrorCode::OrderValidationFailed,
"Order modify cannot combine trailing amount and trailing percent",
false,
Some("Choose either trailing_amount or trailing_percent".to_string()),
));
}
Ok(())
}
}