use anyhow::Result;
use percli_core::POS_SCALE;
use std::path::Path;
use super::state::{self, Operation};
use crate::format::{self, OutputFormat};
use crate::StepAction;
pub fn run(state_path: &str, action: StepAction, fmt: OutputFormat) -> Result<()> {
let path = Path::new(state_path);
let mut state = state::load_or_create(path)?;
let op = action_to_op(&action);
state.operations.push(op);
match &action {
StepAction::Crank { oracle, slot } => {
state.oracle_price = *oracle;
state.slot = *slot;
}
StepAction::SetOracle { price } => {
state.oracle_price = *price;
}
StepAction::SetSlot { slot } => {
state.slot = *slot;
}
_ => {}
}
let engine = state::replay(&state)?;
state::save(path, &state)?;
let snap = engine.snapshot();
format::print_snapshot(&snap, fmt)?;
Ok(())
}
fn action_to_op(action: &StepAction) -> Operation {
match action {
StepAction::Deposit { account, amount } => Operation::Deposit {
account: account.clone(),
amount: *amount as u64,
},
StepAction::Withdraw { account, amount } => Operation::Withdraw {
account: account.clone(),
amount: *amount as u64,
},
StepAction::Trade {
long,
short,
size,
price,
} => Operation::Trade {
long: long.clone(),
short: short.clone(),
size_q: (*size * POS_SCALE as i128) as i64,
price: *price,
},
StepAction::Crank { oracle, slot } => Operation::Crank {
oracle: *oracle,
slot: *slot,
},
StepAction::Liquidate { account } => Operation::Liquidate {
account: account.clone(),
},
StepAction::SetOracle { price } => Operation::SetOracle { price: *price },
StepAction::SetSlot { slot } => Operation::SetSlot { slot: *slot },
}
}