1#![allow(unused_imports)]
15use async_trait::async_trait;
16use derive_builder::Builder;
17use reqwest;
18use rust_decimal::prelude::*;
19use serde::{Deserialize, Serialize};
20use serde_json::{Value, json};
21use std::collections::BTreeMap;
22
23use crate::common::{
24 config::ConfigurationRestApi,
25 models::{ParamBuildError, RestApiResponse},
26 utils::send_request,
27};
28use crate::crypto_loan::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait FlexibleRateApi: Send + Sync {
34 async fn check_collateral_repay_rate(
35 &self,
36 params: CheckCollateralRepayRateParams,
37 ) -> anyhow::Result<RestApiResponse<models::CheckCollateralRepayRateResponse>>;
38 async fn flexible_loan_adjust_ltv(
39 &self,
40 params: FlexibleLoanAdjustLtvParams,
41 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanAdjustLtvResponse>>;
42 async fn flexible_loan_borrow(
43 &self,
44 params: FlexibleLoanBorrowParams,
45 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanBorrowResponse>>;
46 async fn flexible_loan_repay(
47 &self,
48 params: FlexibleLoanRepayParams,
49 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanRepayResponse>>;
50 async fn get_flexible_loan_assets_data(
51 &self,
52 params: GetFlexibleLoanAssetsDataParams,
53 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanAssetsDataResponse>>;
54 async fn get_flexible_loan_borrow_history(
55 &self,
56 params: GetFlexibleLoanBorrowHistoryParams,
57 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanBorrowHistoryResponse>>;
58 async fn get_flexible_loan_collateral_assets_data(
59 &self,
60 params: GetFlexibleLoanCollateralAssetsDataParams,
61 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanCollateralAssetsDataResponse>>;
62 async fn get_flexible_loan_interest_rate_history(
63 &self,
64 params: GetFlexibleLoanInterestRateHistoryParams,
65 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanInterestRateHistoryResponse>>;
66 async fn get_flexible_loan_liquidation_history(
67 &self,
68 params: GetFlexibleLoanLiquidationHistoryParams,
69 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanLiquidationHistoryResponse>>;
70 async fn get_flexible_loan_ltv_adjustment_history(
71 &self,
72 params: GetFlexibleLoanLtvAdjustmentHistoryParams,
73 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanLtvAdjustmentHistoryResponse>>;
74 async fn get_flexible_loan_ongoing_orders(
75 &self,
76 params: GetFlexibleLoanOngoingOrdersParams,
77 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanOngoingOrdersResponse>>;
78 async fn get_flexible_loan_repayment_history(
79 &self,
80 params: GetFlexibleLoanRepaymentHistoryParams,
81 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanRepaymentHistoryResponse>>;
82}
83
84#[derive(Debug, Clone)]
85pub struct FlexibleRateApiClient {
86 configuration: ConfigurationRestApi,
87}
88
89impl FlexibleRateApiClient {
90 pub fn new(configuration: ConfigurationRestApi) -> Self {
91 Self { configuration }
92 }
93}
94
95#[allow(non_camel_case_types)]
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub enum FlexibleLoanAdjustLtvDirectionEnum {
98 #[serde(rename = "ADDITIONAL")]
99 Additional,
100 #[serde(rename = "REDUCED")]
101 Reduced,
102}
103
104impl FlexibleLoanAdjustLtvDirectionEnum {
105 #[must_use]
106 pub fn as_str(&self) -> &'static str {
107 match self {
108 Self::Additional => "ADDITIONAL",
109 Self::Reduced => "REDUCED",
110 }
111 }
112}
113
114impl std::str::FromStr for FlexibleLoanAdjustLtvDirectionEnum {
115 type Err = Box<dyn std::error::Error + Send + Sync>;
116
117 fn from_str(s: &str) -> Result<Self, Self::Err> {
118 match s {
119 "ADDITIONAL" => Ok(Self::Additional),
120 "REDUCED" => Ok(Self::Reduced),
121 other => Err(format!("invalid FlexibleLoanAdjustLtvDirectionEnum: {}", other).into()),
122 }
123 }
124}
125
126#[allow(non_camel_case_types)]
127#[derive(Debug, Clone, Serialize, Deserialize)]
128pub enum FlexibleLoanRepayRepaymentTypeEnum {
129 #[serde(rename = "1")]
130 RepaymentType1,
131 #[serde(rename = "2")]
132 RepaymentType2,
133}
134
135impl FlexibleLoanRepayRepaymentTypeEnum {
136 #[must_use]
137 pub fn as_str(&self) -> &'static str {
138 match self {
139 Self::RepaymentType1 => "1",
140 Self::RepaymentType2 => "2",
141 }
142 }
143}
144
145impl std::str::FromStr for FlexibleLoanRepayRepaymentTypeEnum {
146 type Err = Box<dyn std::error::Error + Send + Sync>;
147
148 fn from_str(s: &str) -> Result<Self, Self::Err> {
149 match s {
150 "1" => Ok(Self::RepaymentType1),
151 "2" => Ok(Self::RepaymentType2),
152 other => Err(format!("invalid FlexibleLoanRepayRepaymentTypeEnum: {}", other).into()),
153 }
154 }
155}
156
157#[derive(Clone, Debug, Builder, Deserialize)]
162#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
163pub struct CheckCollateralRepayRateParams {
164 #[builder(setter(into))]
169 #[serde(rename = "loanCoin")]
170 pub loan_coin: String,
171 #[builder(setter(into))]
176 #[serde(rename = "collateralCoin")]
177 pub collateral_coin: String,
178 #[builder(setter(into), default)]
182 #[serde(rename = "recvWindow", default)]
183 pub recv_window: Option<i64>,
184}
185
186impl CheckCollateralRepayRateParams {
187 #[must_use]
195 pub fn builder(
196 loan_coin: String,
197 collateral_coin: String,
198 ) -> CheckCollateralRepayRateParamsBuilder {
199 CheckCollateralRepayRateParamsBuilder::default()
200 .loan_coin(loan_coin)
201 .collateral_coin(collateral_coin)
202 }
203}
204#[derive(Clone, Debug, Builder, Deserialize)]
209#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
210pub struct FlexibleLoanAdjustLtvParams {
211 #[builder(setter(into))]
216 #[serde(rename = "loanCoin")]
217 pub loan_coin: String,
218 #[builder(setter(into))]
223 #[serde(rename = "collateralCoin")]
224 pub collateral_coin: String,
225 #[builder(setter(into))]
230 #[serde(rename = "adjustmentAmount")]
231 pub adjustment_amount: rust_decimal::Decimal,
232 #[builder(setter(into))]
237 #[serde(rename = "direction")]
238 pub direction: FlexibleLoanAdjustLtvDirectionEnum,
239 #[builder(setter(into), default)]
243 #[serde(rename = "recvWindow", default)]
244 pub recv_window: Option<i64>,
245}
246
247impl FlexibleLoanAdjustLtvParams {
248 #[must_use]
258 pub fn builder(
259 loan_coin: String,
260 collateral_coin: String,
261 adjustment_amount: rust_decimal::Decimal,
262 direction: FlexibleLoanAdjustLtvDirectionEnum,
263 ) -> FlexibleLoanAdjustLtvParamsBuilder {
264 FlexibleLoanAdjustLtvParamsBuilder::default()
265 .loan_coin(loan_coin)
266 .collateral_coin(collateral_coin)
267 .adjustment_amount(adjustment_amount)
268 .direction(direction)
269 }
270}
271#[derive(Clone, Debug, Builder, Deserialize)]
276#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
277pub struct FlexibleLoanBorrowParams {
278 #[builder(setter(into))]
283 #[serde(rename = "loanCoin")]
284 pub loan_coin: String,
285 #[builder(setter(into))]
290 #[serde(rename = "collateralCoin")]
291 pub collateral_coin: String,
292 #[builder(setter(into), default)]
296 #[serde(rename = "loanAmount", default)]
297 pub loan_amount: Option<rust_decimal::Decimal>,
298 #[builder(setter(into), default)]
302 #[serde(rename = "collateralAmount", default)]
303 pub collateral_amount: Option<rust_decimal::Decimal>,
304 #[builder(setter(into), default)]
308 #[serde(rename = "recvWindow", default)]
309 pub recv_window: Option<i64>,
310}
311
312impl FlexibleLoanBorrowParams {
313 #[must_use]
321 pub fn builder(loan_coin: String, collateral_coin: String) -> FlexibleLoanBorrowParamsBuilder {
322 FlexibleLoanBorrowParamsBuilder::default()
323 .loan_coin(loan_coin)
324 .collateral_coin(collateral_coin)
325 }
326}
327#[derive(Clone, Debug, Builder, Deserialize)]
332#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
333pub struct FlexibleLoanRepayParams {
334 #[builder(setter(into))]
339 #[serde(rename = "loanCoin")]
340 pub loan_coin: String,
341 #[builder(setter(into))]
346 #[serde(rename = "collateralCoin")]
347 pub collateral_coin: String,
348 #[builder(setter(into))]
353 #[serde(rename = "repayAmount")]
354 pub repay_amount: rust_decimal::Decimal,
355 #[builder(setter(into), default)]
360 #[serde(rename = "collateralReturn", default)]
361 pub collateral_return: Option<bool>,
362 #[builder(setter(into), default)]
366 #[serde(rename = "fullRepayment", default)]
367 pub full_repayment: Option<bool>,
368 #[builder(setter(into), default)]
372 #[serde(rename = "repaymentType", default)]
373 pub repayment_type: Option<FlexibleLoanRepayRepaymentTypeEnum>,
374 #[builder(setter(into), default)]
378 #[serde(rename = "recvWindow", default)]
379 pub recv_window: Option<i64>,
380}
381
382impl FlexibleLoanRepayParams {
383 #[must_use]
392 pub fn builder(
393 loan_coin: String,
394 collateral_coin: String,
395 repay_amount: rust_decimal::Decimal,
396 ) -> FlexibleLoanRepayParamsBuilder {
397 FlexibleLoanRepayParamsBuilder::default()
398 .loan_coin(loan_coin)
399 .collateral_coin(collateral_coin)
400 .repay_amount(repay_amount)
401 }
402}
403#[derive(Clone, Debug, Builder, Deserialize, Default)]
408#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
409pub struct GetFlexibleLoanAssetsDataParams {
410 #[builder(setter(into), default)]
415 #[serde(rename = "loanCoin", default)]
416 pub loan_coin: Option<String>,
417 #[builder(setter(into), default)]
421 #[serde(rename = "recvWindow", default)]
422 pub recv_window: Option<i64>,
423}
424
425impl GetFlexibleLoanAssetsDataParams {
426 #[must_use]
429 pub fn builder() -> GetFlexibleLoanAssetsDataParamsBuilder {
430 GetFlexibleLoanAssetsDataParamsBuilder::default()
431 }
432}
433#[derive(Clone, Debug, Builder, Deserialize, Default)]
438#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
439pub struct GetFlexibleLoanBorrowHistoryParams {
440 #[builder(setter(into), default)]
445 #[serde(rename = "loanCoin", default)]
446 pub loan_coin: Option<String>,
447 #[builder(setter(into), default)]
452 #[serde(rename = "collateralCoin", default)]
453 pub collateral_coin: Option<String>,
454 #[builder(setter(into), default)]
459 #[serde(rename = "startTime", default)]
460 pub start_time: Option<i64>,
461 #[builder(setter(into), default)]
466 #[serde(rename = "endTime", default)]
467 pub end_time: Option<i64>,
468 #[builder(setter(into), default)]
472 #[serde(rename = "current", default)]
473 pub current: Option<i64>,
474 #[builder(setter(into), default)]
478 #[serde(rename = "limit", default)]
479 pub limit: Option<i64>,
480 #[builder(setter(into), default)]
484 #[serde(rename = "recvWindow", default)]
485 pub recv_window: Option<i64>,
486}
487
488impl GetFlexibleLoanBorrowHistoryParams {
489 #[must_use]
492 pub fn builder() -> GetFlexibleLoanBorrowHistoryParamsBuilder {
493 GetFlexibleLoanBorrowHistoryParamsBuilder::default()
494 }
495}
496#[derive(Clone, Debug, Builder, Deserialize, Default)]
501#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
502pub struct GetFlexibleLoanCollateralAssetsDataParams {
503 #[builder(setter(into), default)]
508 #[serde(rename = "collateralCoin", default)]
509 pub collateral_coin: Option<String>,
510 #[builder(setter(into), default)]
514 #[serde(rename = "recvWindow", default)]
515 pub recv_window: Option<i64>,
516}
517
518impl GetFlexibleLoanCollateralAssetsDataParams {
519 #[must_use]
522 pub fn builder() -> GetFlexibleLoanCollateralAssetsDataParamsBuilder {
523 GetFlexibleLoanCollateralAssetsDataParamsBuilder::default()
524 }
525}
526#[derive(Clone, Debug, Builder, Deserialize)]
531#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
532pub struct GetFlexibleLoanInterestRateHistoryParams {
533 #[builder(setter(into))]
538 #[serde(rename = "coin")]
539 pub coin: String,
540 #[builder(setter(into))]
544 #[serde(rename = "recvWindow")]
545 pub recv_window: i64,
546 #[builder(setter(into), default)]
551 #[serde(rename = "startTime", default)]
552 pub start_time: Option<i64>,
553 #[builder(setter(into), default)]
558 #[serde(rename = "endTime", default)]
559 pub end_time: Option<i64>,
560 #[builder(setter(into), default)]
564 #[serde(rename = "current", default)]
565 pub current: Option<i64>,
566 #[builder(setter(into), default)]
570 #[serde(rename = "limit", default)]
571 pub limit: Option<i64>,
572}
573
574impl GetFlexibleLoanInterestRateHistoryParams {
575 #[must_use]
583 pub fn builder(
584 coin: String,
585 recv_window: i64,
586 ) -> GetFlexibleLoanInterestRateHistoryParamsBuilder {
587 GetFlexibleLoanInterestRateHistoryParamsBuilder::default()
588 .coin(coin)
589 .recv_window(recv_window)
590 }
591}
592#[derive(Clone, Debug, Builder, Deserialize, Default)]
597#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
598pub struct GetFlexibleLoanLiquidationHistoryParams {
599 #[builder(setter(into), default)]
604 #[serde(rename = "loanCoin", default)]
605 pub loan_coin: Option<String>,
606 #[builder(setter(into), default)]
611 #[serde(rename = "collateralCoin", default)]
612 pub collateral_coin: Option<String>,
613 #[builder(setter(into), default)]
618 #[serde(rename = "startTime", default)]
619 pub start_time: Option<i64>,
620 #[builder(setter(into), default)]
625 #[serde(rename = "endTime", default)]
626 pub end_time: Option<i64>,
627 #[builder(setter(into), default)]
631 #[serde(rename = "current", default)]
632 pub current: Option<i64>,
633 #[builder(setter(into), default)]
637 #[serde(rename = "limit", default)]
638 pub limit: Option<i64>,
639 #[builder(setter(into), default)]
643 #[serde(rename = "recvWindow", default)]
644 pub recv_window: Option<i64>,
645}
646
647impl GetFlexibleLoanLiquidationHistoryParams {
648 #[must_use]
651 pub fn builder() -> GetFlexibleLoanLiquidationHistoryParamsBuilder {
652 GetFlexibleLoanLiquidationHistoryParamsBuilder::default()
653 }
654}
655#[derive(Clone, Debug, Builder, Deserialize, Default)]
660#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
661pub struct GetFlexibleLoanLtvAdjustmentHistoryParams {
662 #[builder(setter(into), default)]
667 #[serde(rename = "loanCoin", default)]
668 pub loan_coin: Option<String>,
669 #[builder(setter(into), default)]
674 #[serde(rename = "collateralCoin", default)]
675 pub collateral_coin: Option<String>,
676 #[builder(setter(into), default)]
681 #[serde(rename = "startTime", default)]
682 pub start_time: Option<i64>,
683 #[builder(setter(into), default)]
688 #[serde(rename = "endTime", default)]
689 pub end_time: Option<i64>,
690 #[builder(setter(into), default)]
694 #[serde(rename = "current", default)]
695 pub current: Option<i64>,
696 #[builder(setter(into), default)]
700 #[serde(rename = "limit", default)]
701 pub limit: Option<i64>,
702 #[builder(setter(into), default)]
706 #[serde(rename = "recvWindow", default)]
707 pub recv_window: Option<i64>,
708}
709
710impl GetFlexibleLoanLtvAdjustmentHistoryParams {
711 #[must_use]
714 pub fn builder() -> GetFlexibleLoanLtvAdjustmentHistoryParamsBuilder {
715 GetFlexibleLoanLtvAdjustmentHistoryParamsBuilder::default()
716 }
717}
718#[derive(Clone, Debug, Builder, Deserialize, Default)]
723#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
724pub struct GetFlexibleLoanOngoingOrdersParams {
725 #[builder(setter(into), default)]
730 #[serde(rename = "loanCoin", default)]
731 pub loan_coin: Option<String>,
732 #[builder(setter(into), default)]
737 #[serde(rename = "collateralCoin", default)]
738 pub collateral_coin: Option<String>,
739 #[builder(setter(into), default)]
743 #[serde(rename = "current", default)]
744 pub current: Option<i64>,
745 #[builder(setter(into), default)]
749 #[serde(rename = "limit", default)]
750 pub limit: Option<i64>,
751 #[builder(setter(into), default)]
755 #[serde(rename = "recvWindow", default)]
756 pub recv_window: Option<i64>,
757}
758
759impl GetFlexibleLoanOngoingOrdersParams {
760 #[must_use]
763 pub fn builder() -> GetFlexibleLoanOngoingOrdersParamsBuilder {
764 GetFlexibleLoanOngoingOrdersParamsBuilder::default()
765 }
766}
767#[derive(Clone, Debug, Builder, Deserialize, Default)]
772#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
773pub struct GetFlexibleLoanRepaymentHistoryParams {
774 #[builder(setter(into), default)]
779 #[serde(rename = "loanCoin", default)]
780 pub loan_coin: Option<String>,
781 #[builder(setter(into), default)]
786 #[serde(rename = "collateralCoin", default)]
787 pub collateral_coin: Option<String>,
788 #[builder(setter(into), default)]
793 #[serde(rename = "startTime", default)]
794 pub start_time: Option<i64>,
795 #[builder(setter(into), default)]
800 #[serde(rename = "endTime", default)]
801 pub end_time: Option<i64>,
802 #[builder(setter(into), default)]
806 #[serde(rename = "current", default)]
807 pub current: Option<i64>,
808 #[builder(setter(into), default)]
812 #[serde(rename = "limit", default)]
813 pub limit: Option<i64>,
814 #[builder(setter(into), default)]
818 #[serde(rename = "recvWindow", default)]
819 pub recv_window: Option<i64>,
820}
821
822impl GetFlexibleLoanRepaymentHistoryParams {
823 #[must_use]
826 pub fn builder() -> GetFlexibleLoanRepaymentHistoryParamsBuilder {
827 GetFlexibleLoanRepaymentHistoryParamsBuilder::default()
828 }
829}
830
831#[async_trait]
832impl FlexibleRateApi for FlexibleRateApiClient {
833 async fn check_collateral_repay_rate(
834 &self,
835 params: CheckCollateralRepayRateParams,
836 ) -> anyhow::Result<RestApiResponse<models::CheckCollateralRepayRateResponse>> {
837 let CheckCollateralRepayRateParams {
838 loan_coin,
839 collateral_coin,
840 recv_window,
841 } = params;
842
843 let mut query_params = BTreeMap::new();
844 let body_params = BTreeMap::new();
845
846 query_params.insert("loanCoin".to_string(), json!(loan_coin));
847
848 query_params.insert("collateralCoin".to_string(), json!(collateral_coin));
849
850 if let Some(rw) = recv_window {
851 query_params.insert("recvWindow".to_string(), json!(rw));
852 }
853
854 send_request::<models::CheckCollateralRepayRateResponse>(
855 &self.configuration,
856 "/sapi/v2/loan/flexible/repay/rate",
857 reqwest::Method::GET,
858 query_params,
859 body_params,
860 if HAS_TIME_UNIT {
861 self.configuration.time_unit
862 } else {
863 None
864 },
865 true,
866 )
867 .await
868 }
869
870 async fn flexible_loan_adjust_ltv(
871 &self,
872 params: FlexibleLoanAdjustLtvParams,
873 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanAdjustLtvResponse>> {
874 let FlexibleLoanAdjustLtvParams {
875 loan_coin,
876 collateral_coin,
877 adjustment_amount,
878 direction,
879 recv_window,
880 } = params;
881
882 let mut query_params = BTreeMap::new();
883 let body_params = BTreeMap::new();
884
885 query_params.insert("loanCoin".to_string(), json!(loan_coin));
886
887 query_params.insert("collateralCoin".to_string(), json!(collateral_coin));
888
889 query_params.insert("adjustmentAmount".to_string(), json!(adjustment_amount));
890
891 query_params.insert("direction".to_string(), json!(direction));
892
893 if let Some(rw) = recv_window {
894 query_params.insert("recvWindow".to_string(), json!(rw));
895 }
896
897 send_request::<models::FlexibleLoanAdjustLtvResponse>(
898 &self.configuration,
899 "/sapi/v2/loan/flexible/adjust/ltv",
900 reqwest::Method::POST,
901 query_params,
902 body_params,
903 if HAS_TIME_UNIT {
904 self.configuration.time_unit
905 } else {
906 None
907 },
908 true,
909 )
910 .await
911 }
912
913 async fn flexible_loan_borrow(
914 &self,
915 params: FlexibleLoanBorrowParams,
916 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanBorrowResponse>> {
917 let FlexibleLoanBorrowParams {
918 loan_coin,
919 collateral_coin,
920 loan_amount,
921 collateral_amount,
922 recv_window,
923 } = params;
924
925 let mut query_params = BTreeMap::new();
926 let body_params = BTreeMap::new();
927
928 query_params.insert("loanCoin".to_string(), json!(loan_coin));
929
930 if let Some(rw) = loan_amount {
931 query_params.insert("loanAmount".to_string(), json!(rw));
932 }
933
934 query_params.insert("collateralCoin".to_string(), json!(collateral_coin));
935
936 if let Some(rw) = collateral_amount {
937 query_params.insert("collateralAmount".to_string(), json!(rw));
938 }
939
940 if let Some(rw) = recv_window {
941 query_params.insert("recvWindow".to_string(), json!(rw));
942 }
943
944 send_request::<models::FlexibleLoanBorrowResponse>(
945 &self.configuration,
946 "/sapi/v2/loan/flexible/borrow",
947 reqwest::Method::POST,
948 query_params,
949 body_params,
950 if HAS_TIME_UNIT {
951 self.configuration.time_unit
952 } else {
953 None
954 },
955 true,
956 )
957 .await
958 }
959
960 async fn flexible_loan_repay(
961 &self,
962 params: FlexibleLoanRepayParams,
963 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanRepayResponse>> {
964 let FlexibleLoanRepayParams {
965 loan_coin,
966 collateral_coin,
967 repay_amount,
968 collateral_return,
969 full_repayment,
970 repayment_type,
971 recv_window,
972 } = params;
973
974 let mut query_params = BTreeMap::new();
975 let body_params = BTreeMap::new();
976
977 query_params.insert("loanCoin".to_string(), json!(loan_coin));
978
979 query_params.insert("collateralCoin".to_string(), json!(collateral_coin));
980
981 query_params.insert("repayAmount".to_string(), json!(repay_amount));
982
983 if let Some(rw) = collateral_return {
984 query_params.insert("collateralReturn".to_string(), json!(rw));
985 }
986
987 if let Some(rw) = full_repayment {
988 query_params.insert("fullRepayment".to_string(), json!(rw));
989 }
990
991 if let Some(rw) = repayment_type {
992 query_params.insert("repaymentType".to_string(), json!(rw));
993 }
994
995 if let Some(rw) = recv_window {
996 query_params.insert("recvWindow".to_string(), json!(rw));
997 }
998
999 send_request::<models::FlexibleLoanRepayResponse>(
1000 &self.configuration,
1001 "/sapi/v2/loan/flexible/repay",
1002 reqwest::Method::POST,
1003 query_params,
1004 body_params,
1005 if HAS_TIME_UNIT {
1006 self.configuration.time_unit
1007 } else {
1008 None
1009 },
1010 true,
1011 )
1012 .await
1013 }
1014
1015 async fn get_flexible_loan_assets_data(
1016 &self,
1017 params: GetFlexibleLoanAssetsDataParams,
1018 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanAssetsDataResponse>> {
1019 let GetFlexibleLoanAssetsDataParams {
1020 loan_coin,
1021 recv_window,
1022 } = params;
1023
1024 let mut query_params = BTreeMap::new();
1025 let body_params = BTreeMap::new();
1026
1027 if let Some(rw) = loan_coin {
1028 query_params.insert("loanCoin".to_string(), json!(rw));
1029 }
1030
1031 if let Some(rw) = recv_window {
1032 query_params.insert("recvWindow".to_string(), json!(rw));
1033 }
1034
1035 send_request::<models::GetFlexibleLoanAssetsDataResponse>(
1036 &self.configuration,
1037 "/sapi/v2/loan/flexible/loanable/data",
1038 reqwest::Method::GET,
1039 query_params,
1040 body_params,
1041 if HAS_TIME_UNIT {
1042 self.configuration.time_unit
1043 } else {
1044 None
1045 },
1046 true,
1047 )
1048 .await
1049 }
1050
1051 async fn get_flexible_loan_borrow_history(
1052 &self,
1053 params: GetFlexibleLoanBorrowHistoryParams,
1054 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanBorrowHistoryResponse>> {
1055 let GetFlexibleLoanBorrowHistoryParams {
1056 loan_coin,
1057 collateral_coin,
1058 start_time,
1059 end_time,
1060 current,
1061 limit,
1062 recv_window,
1063 } = params;
1064
1065 let mut query_params = BTreeMap::new();
1066 let body_params = BTreeMap::new();
1067
1068 if let Some(rw) = loan_coin {
1069 query_params.insert("loanCoin".to_string(), json!(rw));
1070 }
1071
1072 if let Some(rw) = collateral_coin {
1073 query_params.insert("collateralCoin".to_string(), json!(rw));
1074 }
1075
1076 if let Some(rw) = start_time {
1077 query_params.insert("startTime".to_string(), json!(rw));
1078 }
1079
1080 if let Some(rw) = end_time {
1081 query_params.insert("endTime".to_string(), json!(rw));
1082 }
1083
1084 if let Some(rw) = current {
1085 query_params.insert("current".to_string(), json!(rw));
1086 }
1087
1088 if let Some(rw) = limit {
1089 query_params.insert("limit".to_string(), json!(rw));
1090 }
1091
1092 if let Some(rw) = recv_window {
1093 query_params.insert("recvWindow".to_string(), json!(rw));
1094 }
1095
1096 send_request::<models::GetFlexibleLoanBorrowHistoryResponse>(
1097 &self.configuration,
1098 "/sapi/v2/loan/flexible/borrow/history",
1099 reqwest::Method::GET,
1100 query_params,
1101 body_params,
1102 if HAS_TIME_UNIT {
1103 self.configuration.time_unit
1104 } else {
1105 None
1106 },
1107 true,
1108 )
1109 .await
1110 }
1111
1112 async fn get_flexible_loan_collateral_assets_data(
1113 &self,
1114 params: GetFlexibleLoanCollateralAssetsDataParams,
1115 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanCollateralAssetsDataResponse>> {
1116 let GetFlexibleLoanCollateralAssetsDataParams {
1117 collateral_coin,
1118 recv_window,
1119 } = params;
1120
1121 let mut query_params = BTreeMap::new();
1122 let body_params = BTreeMap::new();
1123
1124 if let Some(rw) = collateral_coin {
1125 query_params.insert("collateralCoin".to_string(), json!(rw));
1126 }
1127
1128 if let Some(rw) = recv_window {
1129 query_params.insert("recvWindow".to_string(), json!(rw));
1130 }
1131
1132 send_request::<models::GetFlexibleLoanCollateralAssetsDataResponse>(
1133 &self.configuration,
1134 "/sapi/v2/loan/flexible/collateral/data",
1135 reqwest::Method::GET,
1136 query_params,
1137 body_params,
1138 if HAS_TIME_UNIT {
1139 self.configuration.time_unit
1140 } else {
1141 None
1142 },
1143 true,
1144 )
1145 .await
1146 }
1147
1148 async fn get_flexible_loan_interest_rate_history(
1149 &self,
1150 params: GetFlexibleLoanInterestRateHistoryParams,
1151 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanInterestRateHistoryResponse>> {
1152 let GetFlexibleLoanInterestRateHistoryParams {
1153 coin,
1154 recv_window,
1155 start_time,
1156 end_time,
1157 current,
1158 limit,
1159 } = params;
1160
1161 let mut query_params = BTreeMap::new();
1162 let body_params = BTreeMap::new();
1163
1164 query_params.insert("coin".to_string(), json!(coin));
1165
1166 if let Some(rw) = start_time {
1167 query_params.insert("startTime".to_string(), json!(rw));
1168 }
1169
1170 if let Some(rw) = end_time {
1171 query_params.insert("endTime".to_string(), json!(rw));
1172 }
1173
1174 if let Some(rw) = current {
1175 query_params.insert("current".to_string(), json!(rw));
1176 }
1177
1178 if let Some(rw) = limit {
1179 query_params.insert("limit".to_string(), json!(rw));
1180 }
1181
1182 query_params.insert("recvWindow".to_string(), json!(recv_window));
1183
1184 send_request::<models::GetFlexibleLoanInterestRateHistoryResponse>(
1185 &self.configuration,
1186 "/sapi/v2/loan/interestRateHistory",
1187 reqwest::Method::GET,
1188 query_params,
1189 body_params,
1190 if HAS_TIME_UNIT {
1191 self.configuration.time_unit
1192 } else {
1193 None
1194 },
1195 true,
1196 )
1197 .await
1198 }
1199
1200 async fn get_flexible_loan_liquidation_history(
1201 &self,
1202 params: GetFlexibleLoanLiquidationHistoryParams,
1203 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanLiquidationHistoryResponse>> {
1204 let GetFlexibleLoanLiquidationHistoryParams {
1205 loan_coin,
1206 collateral_coin,
1207 start_time,
1208 end_time,
1209 current,
1210 limit,
1211 recv_window,
1212 } = params;
1213
1214 let mut query_params = BTreeMap::new();
1215 let body_params = BTreeMap::new();
1216
1217 if let Some(rw) = loan_coin {
1218 query_params.insert("loanCoin".to_string(), json!(rw));
1219 }
1220
1221 if let Some(rw) = collateral_coin {
1222 query_params.insert("collateralCoin".to_string(), json!(rw));
1223 }
1224
1225 if let Some(rw) = start_time {
1226 query_params.insert("startTime".to_string(), json!(rw));
1227 }
1228
1229 if let Some(rw) = end_time {
1230 query_params.insert("endTime".to_string(), json!(rw));
1231 }
1232
1233 if let Some(rw) = current {
1234 query_params.insert("current".to_string(), json!(rw));
1235 }
1236
1237 if let Some(rw) = limit {
1238 query_params.insert("limit".to_string(), json!(rw));
1239 }
1240
1241 if let Some(rw) = recv_window {
1242 query_params.insert("recvWindow".to_string(), json!(rw));
1243 }
1244
1245 send_request::<models::GetFlexibleLoanLiquidationHistoryResponse>(
1246 &self.configuration,
1247 "/sapi/v2/loan/flexible/liquidation/history",
1248 reqwest::Method::GET,
1249 query_params,
1250 body_params,
1251 if HAS_TIME_UNIT {
1252 self.configuration.time_unit
1253 } else {
1254 None
1255 },
1256 true,
1257 )
1258 .await
1259 }
1260
1261 async fn get_flexible_loan_ltv_adjustment_history(
1262 &self,
1263 params: GetFlexibleLoanLtvAdjustmentHistoryParams,
1264 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanLtvAdjustmentHistoryResponse>> {
1265 let GetFlexibleLoanLtvAdjustmentHistoryParams {
1266 loan_coin,
1267 collateral_coin,
1268 start_time,
1269 end_time,
1270 current,
1271 limit,
1272 recv_window,
1273 } = params;
1274
1275 let mut query_params = BTreeMap::new();
1276 let body_params = BTreeMap::new();
1277
1278 if let Some(rw) = loan_coin {
1279 query_params.insert("loanCoin".to_string(), json!(rw));
1280 }
1281
1282 if let Some(rw) = collateral_coin {
1283 query_params.insert("collateralCoin".to_string(), json!(rw));
1284 }
1285
1286 if let Some(rw) = start_time {
1287 query_params.insert("startTime".to_string(), json!(rw));
1288 }
1289
1290 if let Some(rw) = end_time {
1291 query_params.insert("endTime".to_string(), json!(rw));
1292 }
1293
1294 if let Some(rw) = current {
1295 query_params.insert("current".to_string(), json!(rw));
1296 }
1297
1298 if let Some(rw) = limit {
1299 query_params.insert("limit".to_string(), json!(rw));
1300 }
1301
1302 if let Some(rw) = recv_window {
1303 query_params.insert("recvWindow".to_string(), json!(rw));
1304 }
1305
1306 send_request::<models::GetFlexibleLoanLtvAdjustmentHistoryResponse>(
1307 &self.configuration,
1308 "/sapi/v2/loan/flexible/ltv/adjustment/history",
1309 reqwest::Method::GET,
1310 query_params,
1311 body_params,
1312 if HAS_TIME_UNIT {
1313 self.configuration.time_unit
1314 } else {
1315 None
1316 },
1317 true,
1318 )
1319 .await
1320 }
1321
1322 async fn get_flexible_loan_ongoing_orders(
1323 &self,
1324 params: GetFlexibleLoanOngoingOrdersParams,
1325 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanOngoingOrdersResponse>> {
1326 let GetFlexibleLoanOngoingOrdersParams {
1327 loan_coin,
1328 collateral_coin,
1329 current,
1330 limit,
1331 recv_window,
1332 } = params;
1333
1334 let mut query_params = BTreeMap::new();
1335 let body_params = BTreeMap::new();
1336
1337 if let Some(rw) = loan_coin {
1338 query_params.insert("loanCoin".to_string(), json!(rw));
1339 }
1340
1341 if let Some(rw) = collateral_coin {
1342 query_params.insert("collateralCoin".to_string(), json!(rw));
1343 }
1344
1345 if let Some(rw) = current {
1346 query_params.insert("current".to_string(), json!(rw));
1347 }
1348
1349 if let Some(rw) = limit {
1350 query_params.insert("limit".to_string(), json!(rw));
1351 }
1352
1353 if let Some(rw) = recv_window {
1354 query_params.insert("recvWindow".to_string(), json!(rw));
1355 }
1356
1357 send_request::<models::GetFlexibleLoanOngoingOrdersResponse>(
1358 &self.configuration,
1359 "/sapi/v2/loan/flexible/ongoing/orders",
1360 reqwest::Method::GET,
1361 query_params,
1362 body_params,
1363 if HAS_TIME_UNIT {
1364 self.configuration.time_unit
1365 } else {
1366 None
1367 },
1368 true,
1369 )
1370 .await
1371 }
1372
1373 async fn get_flexible_loan_repayment_history(
1374 &self,
1375 params: GetFlexibleLoanRepaymentHistoryParams,
1376 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanRepaymentHistoryResponse>> {
1377 let GetFlexibleLoanRepaymentHistoryParams {
1378 loan_coin,
1379 collateral_coin,
1380 start_time,
1381 end_time,
1382 current,
1383 limit,
1384 recv_window,
1385 } = params;
1386
1387 let mut query_params = BTreeMap::new();
1388 let body_params = BTreeMap::new();
1389
1390 if let Some(rw) = loan_coin {
1391 query_params.insert("loanCoin".to_string(), json!(rw));
1392 }
1393
1394 if let Some(rw) = collateral_coin {
1395 query_params.insert("collateralCoin".to_string(), json!(rw));
1396 }
1397
1398 if let Some(rw) = start_time {
1399 query_params.insert("startTime".to_string(), json!(rw));
1400 }
1401
1402 if let Some(rw) = end_time {
1403 query_params.insert("endTime".to_string(), json!(rw));
1404 }
1405
1406 if let Some(rw) = current {
1407 query_params.insert("current".to_string(), json!(rw));
1408 }
1409
1410 if let Some(rw) = limit {
1411 query_params.insert("limit".to_string(), json!(rw));
1412 }
1413
1414 if let Some(rw) = recv_window {
1415 query_params.insert("recvWindow".to_string(), json!(rw));
1416 }
1417
1418 send_request::<models::GetFlexibleLoanRepaymentHistoryResponse>(
1419 &self.configuration,
1420 "/sapi/v2/loan/flexible/repay/history",
1421 reqwest::Method::GET,
1422 query_params,
1423 body_params,
1424 if HAS_TIME_UNIT {
1425 self.configuration.time_unit
1426 } else {
1427 None
1428 },
1429 true,
1430 )
1431 .await
1432 }
1433}
1434
1435#[cfg(all(test, feature = "crypto_loan"))]
1436mod tests {
1437 use super::*;
1438 use crate::TOKIO_SHARED_RT;
1439 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
1440 use async_trait::async_trait;
1441 use std::collections::HashMap;
1442
1443 struct DummyRestApiResponse<T> {
1444 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
1445 status: u16,
1446 headers: HashMap<String, String>,
1447 rate_limits: Option<Vec<RestApiRateLimit>>,
1448 }
1449
1450 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
1451 fn from(dummy: DummyRestApiResponse<T>) -> Self {
1452 Self {
1453 data_fn: dummy.inner,
1454 status: dummy.status,
1455 headers: dummy.headers,
1456 rate_limits: dummy.rate_limits,
1457 }
1458 }
1459 }
1460
1461 struct MockFlexibleRateApiClient {
1462 force_error: bool,
1463 }
1464
1465 #[async_trait]
1466 impl FlexibleRateApi for MockFlexibleRateApiClient {
1467 async fn check_collateral_repay_rate(
1468 &self,
1469 _params: CheckCollateralRepayRateParams,
1470 ) -> anyhow::Result<RestApiResponse<models::CheckCollateralRepayRateResponse>> {
1471 if self.force_error {
1472 return Err(ConnectorError::ConnectorClientError {
1473 msg: "ResponseError".to_string(),
1474 code: None,
1475 }
1476 .into());
1477 }
1478
1479 let resp_json: Value = serde_json::from_str(
1480 r#"{"loanCoin":"BUSD","collateralCoin":"BNB","rate":"300.36781234"}"#,
1481 )
1482 .unwrap_or_else(|_| serde_json::json!({}));
1483 let dummy_response: models::CheckCollateralRepayRateResponse =
1484 serde_json::from_value(resp_json.clone())
1485 .expect("should parse into models::CheckCollateralRepayRateResponse");
1486
1487 let dummy = DummyRestApiResponse {
1488 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1489 status: 200,
1490 headers: HashMap::new(),
1491 rate_limits: None,
1492 };
1493
1494 Ok(dummy.into())
1495 }
1496
1497 async fn flexible_loan_adjust_ltv(
1498 &self,
1499 _params: FlexibleLoanAdjustLtvParams,
1500 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanAdjustLtvResponse>> {
1501 if self.force_error {
1502 return Err(ConnectorError::ConnectorClientError {
1503 msg: "ResponseError".to_string(),
1504 code: None,
1505 }
1506 .into());
1507 }
1508
1509 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","adjustmentAmount":"5.235","currentLTV":"0.52","status":"Succeeds"}"#).unwrap_or_else(|_| serde_json::json!({}));
1510 let dummy_response: models::FlexibleLoanAdjustLtvResponse =
1511 serde_json::from_value(resp_json.clone())
1512 .expect("should parse into models::FlexibleLoanAdjustLtvResponse");
1513
1514 let dummy = DummyRestApiResponse {
1515 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1516 status: 200,
1517 headers: HashMap::new(),
1518 rate_limits: None,
1519 };
1520
1521 Ok(dummy.into())
1522 }
1523
1524 async fn flexible_loan_borrow(
1525 &self,
1526 _params: FlexibleLoanBorrowParams,
1527 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanBorrowResponse>> {
1528 if self.force_error {
1529 return Err(ConnectorError::ConnectorClientError {
1530 msg: "ResponseError".to_string(),
1531 code: None,
1532 }
1533 .into());
1534 }
1535
1536 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","loanAmount":"100.5","collateralCoin":"BNB","collateralAmount":"50.5","status":"Succeeds"}"#).unwrap_or_else(|_| serde_json::json!({}));
1537 let dummy_response: models::FlexibleLoanBorrowResponse =
1538 serde_json::from_value(resp_json.clone())
1539 .expect("should parse into models::FlexibleLoanBorrowResponse");
1540
1541 let dummy = DummyRestApiResponse {
1542 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1543 status: 200,
1544 headers: HashMap::new(),
1545 rate_limits: None,
1546 };
1547
1548 Ok(dummy.into())
1549 }
1550
1551 async fn flexible_loan_repay(
1552 &self,
1553 _params: FlexibleLoanRepayParams,
1554 ) -> anyhow::Result<RestApiResponse<models::FlexibleLoanRepayResponse>> {
1555 if self.force_error {
1556 return Err(ConnectorError::ConnectorClientError {
1557 msg: "ResponseError".to_string(),
1558 code: None,
1559 }
1560 .into());
1561 }
1562
1563 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","collateralCoin":"BNB","remainingDebt":"100.5","remainingCollateral":"5.253","fullRepayment":false,"currentLTV":"0.25","repayStatus":"REPAID"}"#).unwrap_or_else(|_| serde_json::json!({}));
1564 let dummy_response: models::FlexibleLoanRepayResponse =
1565 serde_json::from_value(resp_json.clone())
1566 .expect("should parse into models::FlexibleLoanRepayResponse");
1567
1568 let dummy = DummyRestApiResponse {
1569 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1570 status: 200,
1571 headers: HashMap::new(),
1572 rate_limits: None,
1573 };
1574
1575 Ok(dummy.into())
1576 }
1577
1578 async fn get_flexible_loan_assets_data(
1579 &self,
1580 _params: GetFlexibleLoanAssetsDataParams,
1581 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanAssetsDataResponse>> {
1582 if self.force_error {
1583 return Err(ConnectorError::ConnectorClientError {
1584 msg: "ResponseError".to_string(),
1585 code: None,
1586 }
1587 .into());
1588 }
1589
1590 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","flexibleInterestRate":"0.00000491","flexibleMinLimit":"100","flexibleMaxLimit":"1000000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1591 let dummy_response: models::GetFlexibleLoanAssetsDataResponse =
1592 serde_json::from_value(resp_json.clone())
1593 .expect("should parse into models::GetFlexibleLoanAssetsDataResponse");
1594
1595 let dummy = DummyRestApiResponse {
1596 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1597 status: 200,
1598 headers: HashMap::new(),
1599 rate_limits: None,
1600 };
1601
1602 Ok(dummy.into())
1603 }
1604
1605 async fn get_flexible_loan_borrow_history(
1606 &self,
1607 _params: GetFlexibleLoanBorrowHistoryParams,
1608 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanBorrowHistoryResponse>> {
1609 if self.force_error {
1610 return Err(ConnectorError::ConnectorClientError {
1611 msg: "ResponseError".to_string(),
1612 code: None,
1613 }
1614 .into());
1615 }
1616
1617 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","initialLoanAmount":"10000","collateralCoin":"BNB","initialCollateralAmount":"49.27565492","borrowTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1618 let dummy_response: models::GetFlexibleLoanBorrowHistoryResponse =
1619 serde_json::from_value(resp_json.clone())
1620 .expect("should parse into models::GetFlexibleLoanBorrowHistoryResponse");
1621
1622 let dummy = DummyRestApiResponse {
1623 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1624 status: 200,
1625 headers: HashMap::new(),
1626 rate_limits: None,
1627 };
1628
1629 Ok(dummy.into())
1630 }
1631
1632 async fn get_flexible_loan_collateral_assets_data(
1633 &self,
1634 _params: GetFlexibleLoanCollateralAssetsDataParams,
1635 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanCollateralAssetsDataResponse>>
1636 {
1637 if self.force_error {
1638 return Err(ConnectorError::ConnectorClientError {
1639 msg: "ResponseError".to_string(),
1640 code: None,
1641 }
1642 .into());
1643 }
1644
1645 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"collateralCoin":"BNB","initialLTV":"0.65","marginCallLTV":"0.75","liquidationLTV":"0.83","maxLimit":"1000000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1646 let dummy_response: models::GetFlexibleLoanCollateralAssetsDataResponse =
1647 serde_json::from_value(resp_json.clone()).expect(
1648 "should parse into models::GetFlexibleLoanCollateralAssetsDataResponse",
1649 );
1650
1651 let dummy = DummyRestApiResponse {
1652 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1653 status: 200,
1654 headers: HashMap::new(),
1655 rate_limits: None,
1656 };
1657
1658 Ok(dummy.into())
1659 }
1660
1661 async fn get_flexible_loan_interest_rate_history(
1662 &self,
1663 _params: GetFlexibleLoanInterestRateHistoryParams,
1664 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanInterestRateHistoryResponse>>
1665 {
1666 if self.force_error {
1667 return Err(ConnectorError::ConnectorClientError {
1668 msg: "ResponseError".to_string(),
1669 code: None,
1670 }
1671 .into());
1672 }
1673
1674 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"coin":"USDT","annualizedInterestRate":"0.0647","time":1575018510000}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
1675 let dummy_response: models::GetFlexibleLoanInterestRateHistoryResponse =
1676 serde_json::from_value(resp_json.clone())
1677 .expect("should parse into models::GetFlexibleLoanInterestRateHistoryResponse");
1678
1679 let dummy = DummyRestApiResponse {
1680 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1681 status: 200,
1682 headers: HashMap::new(),
1683 rate_limits: None,
1684 };
1685
1686 Ok(dummy.into())
1687 }
1688
1689 async fn get_flexible_loan_liquidation_history(
1690 &self,
1691 _params: GetFlexibleLoanLiquidationHistoryParams,
1692 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanLiquidationHistoryResponse>>
1693 {
1694 if self.force_error {
1695 return Err(ConnectorError::ConnectorClientError {
1696 msg: "ResponseError".to_string(),
1697 code: None,
1698 }
1699 .into());
1700 }
1701
1702 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","liquidationDebt":"10000","collateralCoin":"BNB","liquidationCollateralAmount":"123","returnCollateralAmount":"0.2","liquidationFee":"1.2","liquidationStartingPrice":"49.27565492","liquidationStartingTime":1575018510000,"status":"Liquidated"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1703 let dummy_response: models::GetFlexibleLoanLiquidationHistoryResponse =
1704 serde_json::from_value(resp_json.clone())
1705 .expect("should parse into models::GetFlexibleLoanLiquidationHistoryResponse");
1706
1707 let dummy = DummyRestApiResponse {
1708 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1709 status: 200,
1710 headers: HashMap::new(),
1711 rate_limits: None,
1712 };
1713
1714 Ok(dummy.into())
1715 }
1716
1717 async fn get_flexible_loan_ltv_adjustment_history(
1718 &self,
1719 _params: GetFlexibleLoanLtvAdjustmentHistoryParams,
1720 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanLtvAdjustmentHistoryResponse>>
1721 {
1722 if self.force_error {
1723 return Err(ConnectorError::ConnectorClientError {
1724 msg: "ResponseError".to_string(),
1725 code: None,
1726 }
1727 .into());
1728 }
1729
1730 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","collateralAmount":"5.235","preLTV":"0.78","afterLTV":"0.56","adjustTime":1575018510000}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1731 let dummy_response: models::GetFlexibleLoanLtvAdjustmentHistoryResponse =
1732 serde_json::from_value(resp_json.clone()).expect(
1733 "should parse into models::GetFlexibleLoanLtvAdjustmentHistoryResponse",
1734 );
1735
1736 let dummy = DummyRestApiResponse {
1737 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1738 status: 200,
1739 headers: HashMap::new(),
1740 rate_limits: None,
1741 };
1742
1743 Ok(dummy.into())
1744 }
1745
1746 async fn get_flexible_loan_ongoing_orders(
1747 &self,
1748 _params: GetFlexibleLoanOngoingOrdersParams,
1749 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanOngoingOrdersResponse>> {
1750 if self.force_error {
1751 return Err(ConnectorError::ConnectorClientError {
1752 msg: "ResponseError".to_string(),
1753 code: None,
1754 }
1755 .into());
1756 }
1757
1758 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","totalDebt":"10000","collateralCoin":"BNB","collateralAmount":"49.27565492","currentLTV":"0.57"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1759 let dummy_response: models::GetFlexibleLoanOngoingOrdersResponse =
1760 serde_json::from_value(resp_json.clone())
1761 .expect("should parse into models::GetFlexibleLoanOngoingOrdersResponse");
1762
1763 let dummy = DummyRestApiResponse {
1764 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1765 status: 200,
1766 headers: HashMap::new(),
1767 rate_limits: None,
1768 };
1769
1770 Ok(dummy.into())
1771 }
1772
1773 async fn get_flexible_loan_repayment_history(
1774 &self,
1775 _params: GetFlexibleLoanRepaymentHistoryParams,
1776 ) -> anyhow::Result<RestApiResponse<models::GetFlexibleLoanRepaymentHistoryResponse>>
1777 {
1778 if self.force_error {
1779 return Err(ConnectorError::ConnectorClientError {
1780 msg: "ResponseError".to_string(),
1781 code: None,
1782 }
1783 .into());
1784 }
1785
1786 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB","collateralReturn":"49.27565492","repayStatus":"REPAID","repayTime":1575018510000}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
1787 let dummy_response: models::GetFlexibleLoanRepaymentHistoryResponse =
1788 serde_json::from_value(resp_json.clone())
1789 .expect("should parse into models::GetFlexibleLoanRepaymentHistoryResponse");
1790
1791 let dummy = DummyRestApiResponse {
1792 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1793 status: 200,
1794 headers: HashMap::new(),
1795 rate_limits: None,
1796 };
1797
1798 Ok(dummy.into())
1799 }
1800 }
1801
1802 #[test]
1803 fn check_collateral_repay_rate_required_params_success() {
1804 TOKIO_SHARED_RT.block_on(async {
1805 let client = MockFlexibleRateApiClient { force_error: false };
1806
1807 let params =
1808 CheckCollateralRepayRateParams::builder("BUSD".to_string(), "BNB".to_string())
1809 .build()
1810 .unwrap();
1811
1812 let resp_json: Value = serde_json::from_str(
1813 r#"{"loanCoin":"BUSD","collateralCoin":"BNB","rate":"300.36781234"}"#,
1814 )
1815 .unwrap_or_else(|_| serde_json::json!({}));
1816 let expected_response: models::CheckCollateralRepayRateResponse =
1817 serde_json::from_value(resp_json.clone())
1818 .expect("should parse into models::CheckCollateralRepayRateResponse");
1819
1820 let resp = client
1821 .check_collateral_repay_rate(params)
1822 .await
1823 .expect("Expected a response");
1824 let data_future = resp.data();
1825 let actual_response = data_future.await.unwrap();
1826 assert_eq!(actual_response, expected_response);
1827 });
1828 }
1829
1830 #[test]
1831 fn check_collateral_repay_rate_optional_params_success() {
1832 TOKIO_SHARED_RT.block_on(async {
1833 let client = MockFlexibleRateApiClient { force_error: false };
1834
1835 let params =
1836 CheckCollateralRepayRateParams::builder("BUSD".to_string(), "BNB".to_string())
1837 .recv_window(5000)
1838 .build()
1839 .unwrap();
1840
1841 let resp_json: Value = serde_json::from_str(
1842 r#"{"loanCoin":"BUSD","collateralCoin":"BNB","rate":"300.36781234"}"#,
1843 )
1844 .unwrap_or_else(|_| serde_json::json!({}));
1845 let expected_response: models::CheckCollateralRepayRateResponse =
1846 serde_json::from_value(resp_json.clone())
1847 .expect("should parse into models::CheckCollateralRepayRateResponse");
1848
1849 let resp = client
1850 .check_collateral_repay_rate(params)
1851 .await
1852 .expect("Expected a response");
1853 let data_future = resp.data();
1854 let actual_response = data_future.await.unwrap();
1855 assert_eq!(actual_response, expected_response);
1856 });
1857 }
1858
1859 #[test]
1860 fn check_collateral_repay_rate_response_error() {
1861 TOKIO_SHARED_RT.block_on(async {
1862 let client = MockFlexibleRateApiClient { force_error: true };
1863
1864 let params =
1865 CheckCollateralRepayRateParams::builder("BUSD".to_string(), "BNB".to_string())
1866 .build()
1867 .unwrap();
1868
1869 match client.check_collateral_repay_rate(params).await {
1870 Ok(_) => panic!("Expected an error"),
1871 Err(err) => {
1872 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1873 }
1874 }
1875 });
1876 }
1877
1878 #[test]
1879 fn flexible_loan_adjust_ltv_required_params_success() {
1880 TOKIO_SHARED_RT.block_on(async {
1881 let client = MockFlexibleRateApiClient { force_error: false };
1882
1883 let params = FlexibleLoanAdjustLtvParams::builder("BUSD".to_string(),"BNB".to_string(),dec!(1),FlexibleLoanAdjustLtvDirectionEnum::Additional,).build().unwrap();
1884
1885 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","adjustmentAmount":"5.235","currentLTV":"0.52","status":"Succeeds"}"#).unwrap_or_else(|_| serde_json::json!({}));
1886 let expected_response : models::FlexibleLoanAdjustLtvResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::FlexibleLoanAdjustLtvResponse");
1887
1888 let resp = client.flexible_loan_adjust_ltv(params).await.expect("Expected a response");
1889 let data_future = resp.data();
1890 let actual_response = data_future.await.unwrap();
1891 assert_eq!(actual_response, expected_response);
1892 });
1893 }
1894
1895 #[test]
1896 fn flexible_loan_adjust_ltv_optional_params_success() {
1897 TOKIO_SHARED_RT.block_on(async {
1898 let client = MockFlexibleRateApiClient { force_error: false };
1899
1900 let params = FlexibleLoanAdjustLtvParams::builder("BUSD".to_string(),"BNB".to_string(),dec!(1),FlexibleLoanAdjustLtvDirectionEnum::Additional,).recv_window(5000).build().unwrap();
1901
1902 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","adjustmentAmount":"5.235","currentLTV":"0.52","status":"Succeeds"}"#).unwrap_or_else(|_| serde_json::json!({}));
1903 let expected_response : models::FlexibleLoanAdjustLtvResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::FlexibleLoanAdjustLtvResponse");
1904
1905 let resp = client.flexible_loan_adjust_ltv(params).await.expect("Expected a response");
1906 let data_future = resp.data();
1907 let actual_response = data_future.await.unwrap();
1908 assert_eq!(actual_response, expected_response);
1909 });
1910 }
1911
1912 #[test]
1913 fn flexible_loan_adjust_ltv_response_error() {
1914 TOKIO_SHARED_RT.block_on(async {
1915 let client = MockFlexibleRateApiClient { force_error: true };
1916
1917 let params = FlexibleLoanAdjustLtvParams::builder(
1918 "BUSD".to_string(),
1919 "BNB".to_string(),
1920 dec!(1),
1921 FlexibleLoanAdjustLtvDirectionEnum::Additional,
1922 )
1923 .build()
1924 .unwrap();
1925
1926 match client.flexible_loan_adjust_ltv(params).await {
1927 Ok(_) => panic!("Expected an error"),
1928 Err(err) => {
1929 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1930 }
1931 }
1932 });
1933 }
1934
1935 #[test]
1936 fn flexible_loan_borrow_required_params_success() {
1937 TOKIO_SHARED_RT.block_on(async {
1938 let client = MockFlexibleRateApiClient { force_error: false };
1939
1940 let params = FlexibleLoanBorrowParams::builder("BUSD".to_string(),"BNB".to_string(),).build().unwrap();
1941
1942 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","loanAmount":"100.5","collateralCoin":"BNB","collateralAmount":"50.5","status":"Succeeds"}"#).unwrap_or_else(|_| serde_json::json!({}));
1943 let expected_response : models::FlexibleLoanBorrowResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::FlexibleLoanBorrowResponse");
1944
1945 let resp = client.flexible_loan_borrow(params).await.expect("Expected a response");
1946 let data_future = resp.data();
1947 let actual_response = data_future.await.unwrap();
1948 assert_eq!(actual_response, expected_response);
1949 });
1950 }
1951
1952 #[test]
1953 fn flexible_loan_borrow_optional_params_success() {
1954 TOKIO_SHARED_RT.block_on(async {
1955 let client = MockFlexibleRateApiClient { force_error: false };
1956
1957 let params = FlexibleLoanBorrowParams::builder("BUSD".to_string(),"BNB".to_string(),).loan_amount(dec!(1)).collateral_amount(dec!(1)).recv_window(5000).build().unwrap();
1958
1959 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","loanAmount":"100.5","collateralCoin":"BNB","collateralAmount":"50.5","status":"Succeeds"}"#).unwrap_or_else(|_| serde_json::json!({}));
1960 let expected_response : models::FlexibleLoanBorrowResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::FlexibleLoanBorrowResponse");
1961
1962 let resp = client.flexible_loan_borrow(params).await.expect("Expected a response");
1963 let data_future = resp.data();
1964 let actual_response = data_future.await.unwrap();
1965 assert_eq!(actual_response, expected_response);
1966 });
1967 }
1968
1969 #[test]
1970 fn flexible_loan_borrow_response_error() {
1971 TOKIO_SHARED_RT.block_on(async {
1972 let client = MockFlexibleRateApiClient { force_error: true };
1973
1974 let params = FlexibleLoanBorrowParams::builder("BUSD".to_string(), "BNB".to_string())
1975 .build()
1976 .unwrap();
1977
1978 match client.flexible_loan_borrow(params).await {
1979 Ok(_) => panic!("Expected an error"),
1980 Err(err) => {
1981 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1982 }
1983 }
1984 });
1985 }
1986
1987 #[test]
1988 fn flexible_loan_repay_required_params_success() {
1989 TOKIO_SHARED_RT.block_on(async {
1990 let client = MockFlexibleRateApiClient { force_error: false };
1991
1992 let params = FlexibleLoanRepayParams::builder("BUSD".to_string(),"BNB".to_string(),dec!(1),).build().unwrap();
1993
1994 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","collateralCoin":"BNB","remainingDebt":"100.5","remainingCollateral":"5.253","fullRepayment":false,"currentLTV":"0.25","repayStatus":"REPAID"}"#).unwrap_or_else(|_| serde_json::json!({}));
1995 let expected_response : models::FlexibleLoanRepayResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::FlexibleLoanRepayResponse");
1996
1997 let resp = client.flexible_loan_repay(params).await.expect("Expected a response");
1998 let data_future = resp.data();
1999 let actual_response = data_future.await.unwrap();
2000 assert_eq!(actual_response, expected_response);
2001 });
2002 }
2003
2004 #[test]
2005 fn flexible_loan_repay_optional_params_success() {
2006 TOKIO_SHARED_RT.block_on(async {
2007 let client = MockFlexibleRateApiClient { force_error: false };
2008
2009 let params = FlexibleLoanRepayParams::builder("BUSD".to_string(),"BNB".to_string(),dec!(1),).collateral_return(true).full_repayment(false).repayment_type(FlexibleLoanRepayRepaymentTypeEnum::RepaymentType1).recv_window(5000).build().unwrap();
2010
2011 let resp_json: Value = serde_json::from_str(r#"{"loanCoin":"BUSD","collateralCoin":"BNB","remainingDebt":"100.5","remainingCollateral":"5.253","fullRepayment":false,"currentLTV":"0.25","repayStatus":"REPAID"}"#).unwrap_or_else(|_| serde_json::json!({}));
2012 let expected_response : models::FlexibleLoanRepayResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::FlexibleLoanRepayResponse");
2013
2014 let resp = client.flexible_loan_repay(params).await.expect("Expected a response");
2015 let data_future = resp.data();
2016 let actual_response = data_future.await.unwrap();
2017 assert_eq!(actual_response, expected_response);
2018 });
2019 }
2020
2021 #[test]
2022 fn flexible_loan_repay_response_error() {
2023 TOKIO_SHARED_RT.block_on(async {
2024 let client = MockFlexibleRateApiClient { force_error: true };
2025
2026 let params =
2027 FlexibleLoanRepayParams::builder("BUSD".to_string(), "BNB".to_string(), dec!(1))
2028 .build()
2029 .unwrap();
2030
2031 match client.flexible_loan_repay(params).await {
2032 Ok(_) => panic!("Expected an error"),
2033 Err(err) => {
2034 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2035 }
2036 }
2037 });
2038 }
2039
2040 #[test]
2041 fn get_flexible_loan_assets_data_required_params_success() {
2042 TOKIO_SHARED_RT.block_on(async {
2043 let client = MockFlexibleRateApiClient { force_error: false };
2044
2045 let params = GetFlexibleLoanAssetsDataParams::builder().build().unwrap();
2046
2047 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","flexibleInterestRate":"0.00000491","flexibleMinLimit":"100","flexibleMaxLimit":"1000000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2048 let expected_response : models::GetFlexibleLoanAssetsDataResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanAssetsDataResponse");
2049
2050 let resp = client.get_flexible_loan_assets_data(params).await.expect("Expected a response");
2051 let data_future = resp.data();
2052 let actual_response = data_future.await.unwrap();
2053 assert_eq!(actual_response, expected_response);
2054 });
2055 }
2056
2057 #[test]
2058 fn get_flexible_loan_assets_data_optional_params_success() {
2059 TOKIO_SHARED_RT.block_on(async {
2060 let client = MockFlexibleRateApiClient { force_error: false };
2061
2062 let params = GetFlexibleLoanAssetsDataParams::builder().loan_coin("BUSD".to_string()).recv_window(5000).build().unwrap();
2063
2064 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","flexibleInterestRate":"0.00000491","flexibleMinLimit":"100","flexibleMaxLimit":"1000000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2065 let expected_response : models::GetFlexibleLoanAssetsDataResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanAssetsDataResponse");
2066
2067 let resp = client.get_flexible_loan_assets_data(params).await.expect("Expected a response");
2068 let data_future = resp.data();
2069 let actual_response = data_future.await.unwrap();
2070 assert_eq!(actual_response, expected_response);
2071 });
2072 }
2073
2074 #[test]
2075 fn get_flexible_loan_assets_data_response_error() {
2076 TOKIO_SHARED_RT.block_on(async {
2077 let client = MockFlexibleRateApiClient { force_error: true };
2078
2079 let params = GetFlexibleLoanAssetsDataParams::builder().build().unwrap();
2080
2081 match client.get_flexible_loan_assets_data(params).await {
2082 Ok(_) => panic!("Expected an error"),
2083 Err(err) => {
2084 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2085 }
2086 }
2087 });
2088 }
2089
2090 #[test]
2091 fn get_flexible_loan_borrow_history_required_params_success() {
2092 TOKIO_SHARED_RT.block_on(async {
2093 let client = MockFlexibleRateApiClient { force_error: false };
2094
2095 let params = GetFlexibleLoanBorrowHistoryParams::builder().build().unwrap();
2096
2097 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","initialLoanAmount":"10000","collateralCoin":"BNB","initialCollateralAmount":"49.27565492","borrowTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2098 let expected_response : models::GetFlexibleLoanBorrowHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanBorrowHistoryResponse");
2099
2100 let resp = client.get_flexible_loan_borrow_history(params).await.expect("Expected a response");
2101 let data_future = resp.data();
2102 let actual_response = data_future.await.unwrap();
2103 assert_eq!(actual_response, expected_response);
2104 });
2105 }
2106
2107 #[test]
2108 fn get_flexible_loan_borrow_history_optional_params_success() {
2109 TOKIO_SHARED_RT.block_on(async {
2110 let client = MockFlexibleRateApiClient { force_error: false };
2111
2112 let params = GetFlexibleLoanBorrowHistoryParams::builder().loan_coin("BUSD".to_string()).collateral_coin("BNB".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
2113
2114 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","initialLoanAmount":"10000","collateralCoin":"BNB","initialCollateralAmount":"49.27565492","borrowTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2115 let expected_response : models::GetFlexibleLoanBorrowHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanBorrowHistoryResponse");
2116
2117 let resp = client.get_flexible_loan_borrow_history(params).await.expect("Expected a response");
2118 let data_future = resp.data();
2119 let actual_response = data_future.await.unwrap();
2120 assert_eq!(actual_response, expected_response);
2121 });
2122 }
2123
2124 #[test]
2125 fn get_flexible_loan_borrow_history_response_error() {
2126 TOKIO_SHARED_RT.block_on(async {
2127 let client = MockFlexibleRateApiClient { force_error: true };
2128
2129 let params = GetFlexibleLoanBorrowHistoryParams::builder()
2130 .build()
2131 .unwrap();
2132
2133 match client.get_flexible_loan_borrow_history(params).await {
2134 Ok(_) => panic!("Expected an error"),
2135 Err(err) => {
2136 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2137 }
2138 }
2139 });
2140 }
2141
2142 #[test]
2143 fn get_flexible_loan_collateral_assets_data_required_params_success() {
2144 TOKIO_SHARED_RT.block_on(async {
2145 let client = MockFlexibleRateApiClient { force_error: false };
2146
2147 let params = GetFlexibleLoanCollateralAssetsDataParams::builder().build().unwrap();
2148
2149 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"collateralCoin":"BNB","initialLTV":"0.65","marginCallLTV":"0.75","liquidationLTV":"0.83","maxLimit":"1000000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2150 let expected_response : models::GetFlexibleLoanCollateralAssetsDataResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanCollateralAssetsDataResponse");
2151
2152 let resp = client.get_flexible_loan_collateral_assets_data(params).await.expect("Expected a response");
2153 let data_future = resp.data();
2154 let actual_response = data_future.await.unwrap();
2155 assert_eq!(actual_response, expected_response);
2156 });
2157 }
2158
2159 #[test]
2160 fn get_flexible_loan_collateral_assets_data_optional_params_success() {
2161 TOKIO_SHARED_RT.block_on(async {
2162 let client = MockFlexibleRateApiClient { force_error: false };
2163
2164 let params = GetFlexibleLoanCollateralAssetsDataParams::builder().collateral_coin("BNB".to_string()).recv_window(5000).build().unwrap();
2165
2166 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"collateralCoin":"BNB","initialLTV":"0.65","marginCallLTV":"0.75","liquidationLTV":"0.83","maxLimit":"1000000"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2167 let expected_response : models::GetFlexibleLoanCollateralAssetsDataResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanCollateralAssetsDataResponse");
2168
2169 let resp = client.get_flexible_loan_collateral_assets_data(params).await.expect("Expected a response");
2170 let data_future = resp.data();
2171 let actual_response = data_future.await.unwrap();
2172 assert_eq!(actual_response, expected_response);
2173 });
2174 }
2175
2176 #[test]
2177 fn get_flexible_loan_collateral_assets_data_response_error() {
2178 TOKIO_SHARED_RT.block_on(async {
2179 let client = MockFlexibleRateApiClient { force_error: true };
2180
2181 let params = GetFlexibleLoanCollateralAssetsDataParams::builder()
2182 .build()
2183 .unwrap();
2184
2185 match client
2186 .get_flexible_loan_collateral_assets_data(params)
2187 .await
2188 {
2189 Ok(_) => panic!("Expected an error"),
2190 Err(err) => {
2191 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2192 }
2193 }
2194 });
2195 }
2196
2197 #[test]
2198 fn get_flexible_loan_interest_rate_history_required_params_success() {
2199 TOKIO_SHARED_RT.block_on(async {
2200 let client = MockFlexibleRateApiClient { force_error: false };
2201
2202 let params = GetFlexibleLoanInterestRateHistoryParams::builder("USDT".to_string(),5000,).build().unwrap();
2203
2204 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"coin":"USDT","annualizedInterestRate":"0.0647","time":1575018510000}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2205 let expected_response : models::GetFlexibleLoanInterestRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanInterestRateHistoryResponse");
2206
2207 let resp = client.get_flexible_loan_interest_rate_history(params).await.expect("Expected a response");
2208 let data_future = resp.data();
2209 let actual_response = data_future.await.unwrap();
2210 assert_eq!(actual_response, expected_response);
2211 });
2212 }
2213
2214 #[test]
2215 fn get_flexible_loan_interest_rate_history_optional_params_success() {
2216 TOKIO_SHARED_RT.block_on(async {
2217 let client = MockFlexibleRateApiClient { force_error: false };
2218
2219 let params = GetFlexibleLoanInterestRateHistoryParams::builder("USDT".to_string(),5000,).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).build().unwrap();
2220
2221 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"coin":"USDT","annualizedInterestRate":"0.0647","time":1575018510000}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2222 let expected_response : models::GetFlexibleLoanInterestRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanInterestRateHistoryResponse");
2223
2224 let resp = client.get_flexible_loan_interest_rate_history(params).await.expect("Expected a response");
2225 let data_future = resp.data();
2226 let actual_response = data_future.await.unwrap();
2227 assert_eq!(actual_response, expected_response);
2228 });
2229 }
2230
2231 #[test]
2232 fn get_flexible_loan_interest_rate_history_response_error() {
2233 TOKIO_SHARED_RT.block_on(async {
2234 let client = MockFlexibleRateApiClient { force_error: true };
2235
2236 let params =
2237 GetFlexibleLoanInterestRateHistoryParams::builder("USDT".to_string(), 5000)
2238 .build()
2239 .unwrap();
2240
2241 match client.get_flexible_loan_interest_rate_history(params).await {
2242 Ok(_) => panic!("Expected an error"),
2243 Err(err) => {
2244 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2245 }
2246 }
2247 });
2248 }
2249
2250 #[test]
2251 fn get_flexible_loan_liquidation_history_required_params_success() {
2252 TOKIO_SHARED_RT.block_on(async {
2253 let client = MockFlexibleRateApiClient { force_error: false };
2254
2255 let params = GetFlexibleLoanLiquidationHistoryParams::builder().build().unwrap();
2256
2257 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","liquidationDebt":"10000","collateralCoin":"BNB","liquidationCollateralAmount":"123","returnCollateralAmount":"0.2","liquidationFee":"1.2","liquidationStartingPrice":"49.27565492","liquidationStartingTime":1575018510000,"status":"Liquidated"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2258 let expected_response : models::GetFlexibleLoanLiquidationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanLiquidationHistoryResponse");
2259
2260 let resp = client.get_flexible_loan_liquidation_history(params).await.expect("Expected a response");
2261 let data_future = resp.data();
2262 let actual_response = data_future.await.unwrap();
2263 assert_eq!(actual_response, expected_response);
2264 });
2265 }
2266
2267 #[test]
2268 fn get_flexible_loan_liquidation_history_optional_params_success() {
2269 TOKIO_SHARED_RT.block_on(async {
2270 let client = MockFlexibleRateApiClient { force_error: false };
2271
2272 let params = GetFlexibleLoanLiquidationHistoryParams::builder().loan_coin("BUSD".to_string()).collateral_coin("BNB".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
2273
2274 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","liquidationDebt":"10000","collateralCoin":"BNB","liquidationCollateralAmount":"123","returnCollateralAmount":"0.2","liquidationFee":"1.2","liquidationStartingPrice":"49.27565492","liquidationStartingTime":1575018510000,"status":"Liquidated"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2275 let expected_response : models::GetFlexibleLoanLiquidationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanLiquidationHistoryResponse");
2276
2277 let resp = client.get_flexible_loan_liquidation_history(params).await.expect("Expected a response");
2278 let data_future = resp.data();
2279 let actual_response = data_future.await.unwrap();
2280 assert_eq!(actual_response, expected_response);
2281 });
2282 }
2283
2284 #[test]
2285 fn get_flexible_loan_liquidation_history_response_error() {
2286 TOKIO_SHARED_RT.block_on(async {
2287 let client = MockFlexibleRateApiClient { force_error: true };
2288
2289 let params = GetFlexibleLoanLiquidationHistoryParams::builder()
2290 .build()
2291 .unwrap();
2292
2293 match client.get_flexible_loan_liquidation_history(params).await {
2294 Ok(_) => panic!("Expected an error"),
2295 Err(err) => {
2296 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2297 }
2298 }
2299 });
2300 }
2301
2302 #[test]
2303 fn get_flexible_loan_ltv_adjustment_history_required_params_success() {
2304 TOKIO_SHARED_RT.block_on(async {
2305 let client = MockFlexibleRateApiClient { force_error: false };
2306
2307 let params = GetFlexibleLoanLtvAdjustmentHistoryParams::builder().build().unwrap();
2308
2309 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","collateralAmount":"5.235","preLTV":"0.78","afterLTV":"0.56","adjustTime":1575018510000}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2310 let expected_response : models::GetFlexibleLoanLtvAdjustmentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanLtvAdjustmentHistoryResponse");
2311
2312 let resp = client.get_flexible_loan_ltv_adjustment_history(params).await.expect("Expected a response");
2313 let data_future = resp.data();
2314 let actual_response = data_future.await.unwrap();
2315 assert_eq!(actual_response, expected_response);
2316 });
2317 }
2318
2319 #[test]
2320 fn get_flexible_loan_ltv_adjustment_history_optional_params_success() {
2321 TOKIO_SHARED_RT.block_on(async {
2322 let client = MockFlexibleRateApiClient { force_error: false };
2323
2324 let params = GetFlexibleLoanLtvAdjustmentHistoryParams::builder().loan_coin("BUSD".to_string()).collateral_coin("BNB".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
2325
2326 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","collateralAmount":"5.235","preLTV":"0.78","afterLTV":"0.56","adjustTime":1575018510000}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2327 let expected_response : models::GetFlexibleLoanLtvAdjustmentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanLtvAdjustmentHistoryResponse");
2328
2329 let resp = client.get_flexible_loan_ltv_adjustment_history(params).await.expect("Expected a response");
2330 let data_future = resp.data();
2331 let actual_response = data_future.await.unwrap();
2332 assert_eq!(actual_response, expected_response);
2333 });
2334 }
2335
2336 #[test]
2337 fn get_flexible_loan_ltv_adjustment_history_response_error() {
2338 TOKIO_SHARED_RT.block_on(async {
2339 let client = MockFlexibleRateApiClient { force_error: true };
2340
2341 let params = GetFlexibleLoanLtvAdjustmentHistoryParams::builder()
2342 .build()
2343 .unwrap();
2344
2345 match client
2346 .get_flexible_loan_ltv_adjustment_history(params)
2347 .await
2348 {
2349 Ok(_) => panic!("Expected an error"),
2350 Err(err) => {
2351 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2352 }
2353 }
2354 });
2355 }
2356
2357 #[test]
2358 fn get_flexible_loan_ongoing_orders_required_params_success() {
2359 TOKIO_SHARED_RT.block_on(async {
2360 let client = MockFlexibleRateApiClient { force_error: false };
2361
2362 let params = GetFlexibleLoanOngoingOrdersParams::builder().build().unwrap();
2363
2364 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","totalDebt":"10000","collateralCoin":"BNB","collateralAmount":"49.27565492","currentLTV":"0.57"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2365 let expected_response : models::GetFlexibleLoanOngoingOrdersResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanOngoingOrdersResponse");
2366
2367 let resp = client.get_flexible_loan_ongoing_orders(params).await.expect("Expected a response");
2368 let data_future = resp.data();
2369 let actual_response = data_future.await.unwrap();
2370 assert_eq!(actual_response, expected_response);
2371 });
2372 }
2373
2374 #[test]
2375 fn get_flexible_loan_ongoing_orders_optional_params_success() {
2376 TOKIO_SHARED_RT.block_on(async {
2377 let client = MockFlexibleRateApiClient { force_error: false };
2378
2379 let params = GetFlexibleLoanOngoingOrdersParams::builder().loan_coin("BUSD".to_string()).collateral_coin("BNB".to_string()).current(1).limit(10).recv_window(5000).build().unwrap();
2380
2381 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","totalDebt":"10000","collateralCoin":"BNB","collateralAmount":"49.27565492","currentLTV":"0.57"}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2382 let expected_response : models::GetFlexibleLoanOngoingOrdersResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanOngoingOrdersResponse");
2383
2384 let resp = client.get_flexible_loan_ongoing_orders(params).await.expect("Expected a response");
2385 let data_future = resp.data();
2386 let actual_response = data_future.await.unwrap();
2387 assert_eq!(actual_response, expected_response);
2388 });
2389 }
2390
2391 #[test]
2392 fn get_flexible_loan_ongoing_orders_response_error() {
2393 TOKIO_SHARED_RT.block_on(async {
2394 let client = MockFlexibleRateApiClient { force_error: true };
2395
2396 let params = GetFlexibleLoanOngoingOrdersParams::builder()
2397 .build()
2398 .unwrap();
2399
2400 match client.get_flexible_loan_ongoing_orders(params).await {
2401 Ok(_) => panic!("Expected an error"),
2402 Err(err) => {
2403 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2404 }
2405 }
2406 });
2407 }
2408
2409 #[test]
2410 fn get_flexible_loan_repayment_history_required_params_success() {
2411 TOKIO_SHARED_RT.block_on(async {
2412 let client = MockFlexibleRateApiClient { force_error: false };
2413
2414 let params = GetFlexibleLoanRepaymentHistoryParams::builder().build().unwrap();
2415
2416 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB","collateralReturn":"49.27565492","repayStatus":"REPAID","repayTime":1575018510000}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2417 let expected_response : models::GetFlexibleLoanRepaymentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanRepaymentHistoryResponse");
2418
2419 let resp = client.get_flexible_loan_repayment_history(params).await.expect("Expected a response");
2420 let data_future = resp.data();
2421 let actual_response = data_future.await.unwrap();
2422 assert_eq!(actual_response, expected_response);
2423 });
2424 }
2425
2426 #[test]
2427 fn get_flexible_loan_repayment_history_optional_params_success() {
2428 TOKIO_SHARED_RT.block_on(async {
2429 let client = MockFlexibleRateApiClient { force_error: false };
2430
2431 let params = GetFlexibleLoanRepaymentHistoryParams::builder().loan_coin("BUSD".to_string()).collateral_coin("BNB".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
2432
2433 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB","collateralReturn":"49.27565492","repayStatus":"REPAID","repayTime":1575018510000}],"total":1}"#).unwrap_or_else(|_| serde_json::json!({}));
2434 let expected_response : models::GetFlexibleLoanRepaymentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleLoanRepaymentHistoryResponse");
2435
2436 let resp = client.get_flexible_loan_repayment_history(params).await.expect("Expected a response");
2437 let data_future = resp.data();
2438 let actual_response = data_future.await.unwrap();
2439 assert_eq!(actual_response, expected_response);
2440 });
2441 }
2442
2443 #[test]
2444 fn get_flexible_loan_repayment_history_response_error() {
2445 TOKIO_SHARED_RT.block_on(async {
2446 let client = MockFlexibleRateApiClient { force_error: true };
2447
2448 let params = GetFlexibleLoanRepaymentHistoryParams::builder()
2449 .build()
2450 .unwrap();
2451
2452 match client.get_flexible_loan_repayment_history(params).await {
2453 Ok(_) => panic!("Expected an error"),
2454 Err(err) => {
2455 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2456 }
2457 }
2458 });
2459 }
2460}