use http::Method;
use http_endpoint::Bytes;
use serde::Deserialize;
use serde::Serialize;
use serde_json::to_vec as to_json;
use crate::Str;
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[non_exhaustive]
pub enum TradeConfirmation {
#[serde(rename = "all")]
Email,
#[serde(rename = "none")]
None,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Configuration {
#[serde(rename = "trade_confirm_email")]
pub trade_confirmation: TradeConfirmation,
#[serde(rename = "suspend_trade")]
pub trading_suspended: bool,
#[serde(rename = "no_shorting")]
pub no_shorting: bool,
#[doc(hidden)]
#[serde(skip)]
pub _non_exhaustive: (),
}
Endpoint! {
pub Get(()),
Ok => Configuration, [
OK,
],
Err => GetError, []
#[inline]
fn path(_input: &Self::Input) -> Str {
"/v2/account/configurations".into()
}
}
Endpoint! {
pub Change(Configuration),
Ok => Configuration, [
OK,
],
Err => ChangeError, [
BAD_REQUEST => InvalidValues,
]
#[inline]
fn method() -> Method {
Method::PATCH
}
#[inline]
fn path(_input: &Self::Input) -> Str {
"/v2/account/configurations".into()
}
fn body(input: &Self::Input) -> Result<Option<Bytes>, Self::ConversionError> {
let json = to_json(input)?;
let bytes = Bytes::from(json);
Ok(Some(bytes))
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::from_str as from_json;
use test_log::test;
use crate::api_info::ApiInfo;
use crate::Client;
#[test]
fn parse_reference_configuration() {
let response = r#"{
"dtbp_check": "entry",
"no_shorting": false,
"suspend_trade": false,
"trade_confirm_email": "all"
}"#;
let config = from_json::<Configuration>(response).unwrap();
assert_eq!(config.trade_confirmation, TradeConfirmation::Email);
assert!(!config.trading_suspended);
assert!(!config.no_shorting);
}
#[test(tokio::test)]
async fn retrieve_and_update_configuration() {
let api_info = ApiInfo::from_env().unwrap();
let client = Client::new(api_info);
let config = client.issue::<Get>(&()).await.unwrap();
let new_confirmation = match config.trade_confirmation {
TradeConfirmation::Email => TradeConfirmation::None,
TradeConfirmation::None => TradeConfirmation::Email,
};
let changed = Configuration {
trade_confirmation: new_confirmation,
..config
};
let change_result = client.issue::<Change>(&changed).await;
let get_result = client.issue::<Get>(&()).await;
let reverted = client.issue::<Change>(&config).await.unwrap();
assert_eq!(change_result.unwrap(), changed);
assert_eq!(get_result.unwrap(), changed);
assert_eq!(reverted, config);
}
}