use std::{
cell::RefCell,
future::{Future, ready},
pin::pin,
task::{Context, Poll, Waker},
};
use crate::client::{Transport, TransportError};
use crate::utils::{Address, Dec};
pub const SPOT_UNIFIED: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/spot_unified.json"));
pub const PERP_UNIFIED: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/perp_unified.json"));
pub const PERP_UNIFIED_XYZ: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/perp_unified_xyz.json"));
pub const PORTFOLIO_UNIFIED: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/portfolio_unified.json"));
pub const SUBS_UNIFIED: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/subs_unified.json"));
pub const FEES_UNIFIED: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/fees_unified.json"));
pub const RATE_LIMIT_UNIFIED: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/rate_limit_unified.json"));
pub const SPOT_STANDARD: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/spot_standard.json"));
pub const PERP_STANDARD: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/perp_standard.json"));
pub const PERP_STANDARD_XYZ: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/perp_standard_xyz.json"));
pub const VAULTS_STANDARD: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/vaults_standard.json"));
pub const PORTFOLIO_STANDARD: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/portfolio_standard.json"));
pub const PRICES: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/prices.json"));
pub const BUILDER_PERP: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/builder_perp.json"));
pub const BUILDER_PERP_TESTNET: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/builder_perp_testnet.json"));
pub const BUILDER_SPOT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/spot_builder.json"));
pub const BUILDER_AGENTS: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/agents_builder.json"));
pub const BUILDER_AGENTS_TESTNET: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/agents_builder_testnet.json"));
pub const BUILDER_REFERRAL: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/referral_builder.json"));
pub const BUILDER_REFERRAL_TESTNET: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/referral_builder_testnet.json"));
pub const RATE_LIMIT_BUILDER: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/rate_limit_builder.json"));
pub const RATE_LIMIT_BUILDER_TESTNET: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/rate_limit_builder_testnet.json"));
pub const ROLE_AGENT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/role_agent.json"));
pub const ROLE_SUB: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/role_sub.json"));
pub const ROLE_VAULT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/role_vault.json"));
pub const SPOT_PORTFOLIO_MARGIN: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/fixtures/account/spot_portfolio_margin.json"));
pub const UNIFIED: &str = "0x114dc2c90b61ef68b6ccb45d8e9902609cb08f9d";
pub const UNIFIED_SUB: &str = "0x1a16ca90bc961b6bce46f400be2afb0f9f71b93f";
pub const STANDARD: &str = "0x677d831aef5328190852e24f13c46cac05f984e7";
pub const BUILDER: &str = "0x6967d7acd1ec5f210e9590666498e0cc5d13a843";
pub fn dec(text: &str) -> Dec {
Dec::parse(text).unwrap()
}
pub fn address(text: &str) -> Address {
text.parse().unwrap()
}
pub fn read<T: serde::de::DeserializeOwned>(text: &str) -> T {
serde_json::from_str(text).unwrap()
}
pub struct Recorded {
pub answers: Vec<(String, &'static str)>,
pub sent: RefCell<Vec<(String, String)>>,
}
impl Recorded {
pub fn new(answers: &[(&str, &'static str)]) -> Recorded {
Recorded {
answers: answers.iter().map(|(body, answer)| ((*body).to_owned(), *answer)).collect(),
sent: RefCell::new(Vec::new()),
}
}
pub fn asked(&self) -> Vec<String> {
self.sent.borrow().iter().map(|(_, body)| body.clone()).collect()
}
}
impl Transport for Recorded {
fn post(&self, path: &str, body: String) -> impl Future<Output = Result<String, TransportError>> {
let answer = self.answers.iter().find(|(asked, _)| *asked == body).map(|(_, answer)| (*answer).to_owned());
self.sent.borrow_mut().push((path.to_owned(), body.clone()));
ready(answer.ok_or_else(|| TransportError::Unreachable(format!("no recording for {body}"))))
}
}
pub fn block_on<F: Future>(future: F) -> F::Output {
let mut future = pin!(future);
let mut context = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(value) = future.as_mut().poll(&mut context) {
return value;
}
}
}