Skip to main content

binance_sdk/crypto_loan/rest_api/apis/
stable_rate_api.rs

1/*
2 * Binance Crypto Loan REST API
3 *
4 * OpenAPI Specification for the Binance Crypto Loan REST API
5 *
6 * The version of the OpenAPI document: 1.0.0
7 *
8 *
9 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
10 * https://openapi-generator.tech
11 * Do not edit the class manually.
12 */
13
14#![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 StableRateApi: Send + Sync {
34    async fn check_collateral_repay_rate_stable_rate(
35        &self,
36        params: CheckCollateralRepayRateStableRateParams,
37    ) -> anyhow::Result<RestApiResponse<models::CheckCollateralRepayRateStableRateResponse>>;
38    async fn get_crypto_loans_income_history(
39        &self,
40        params: GetCryptoLoansIncomeHistoryParams,
41    ) -> anyhow::Result<RestApiResponse<Vec<models::GetCryptoLoansIncomeHistoryResponseInner>>>;
42    async fn get_loan_borrow_history(
43        &self,
44        params: GetLoanBorrowHistoryParams,
45    ) -> anyhow::Result<RestApiResponse<models::GetLoanBorrowHistoryResponse>>;
46    async fn get_loan_ltv_adjustment_history(
47        &self,
48        params: GetLoanLtvAdjustmentHistoryParams,
49    ) -> anyhow::Result<RestApiResponse<models::GetLoanLtvAdjustmentHistoryResponse>>;
50    async fn get_loan_repayment_history(
51        &self,
52        params: GetLoanRepaymentHistoryParams,
53    ) -> anyhow::Result<RestApiResponse<models::GetLoanRepaymentHistoryResponse>>;
54}
55
56#[derive(Debug, Clone)]
57pub struct StableRateApiClient {
58    configuration: ConfigurationRestApi,
59}
60
61impl StableRateApiClient {
62    pub fn new(configuration: ConfigurationRestApi) -> Self {
63        Self { configuration }
64    }
65}
66
67/// Request parameters for the [`check_collateral_repay_rate_stable_rate`] operation.
68///
69/// This struct holds all of the inputs you can pass when calling
70/// [`check_collateral_repay_rate_stable_rate`](#method.check_collateral_repay_rate_stable_rate).
71#[derive(Clone, Debug, Builder)]
72#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
73pub struct CheckCollateralRepayRateStableRateParams {
74    ///
75    /// The `loan_coin` parameter.
76    ///
77    /// This field is **required.
78    #[builder(setter(into))]
79    pub loan_coin: String,
80    ///
81    /// The `collateral_coin` parameter.
82    ///
83    /// This field is **required.
84    #[builder(setter(into))]
85    pub collateral_coin: String,
86    /// repay amount of loanCoin
87    ///
88    /// This field is **required.
89    #[builder(setter(into))]
90    pub repay_amount: rust_decimal::Decimal,
91    ///
92    /// The `recv_window` parameter.
93    ///
94    /// This field is **optional.
95    #[builder(setter(into), default)]
96    pub recv_window: Option<i64>,
97}
98
99impl CheckCollateralRepayRateStableRateParams {
100    /// Create a builder for [`check_collateral_repay_rate_stable_rate`].
101    ///
102    /// Required parameters:
103    ///
104    /// * `loan_coin` — String
105    /// * `collateral_coin` — String
106    /// * `repay_amount` — repay amount of loanCoin
107    ///
108    #[must_use]
109    pub fn builder(
110        loan_coin: String,
111        collateral_coin: String,
112        repay_amount: rust_decimal::Decimal,
113    ) -> CheckCollateralRepayRateStableRateParamsBuilder {
114        CheckCollateralRepayRateStableRateParamsBuilder::default()
115            .loan_coin(loan_coin)
116            .collateral_coin(collateral_coin)
117            .repay_amount(repay_amount)
118    }
119}
120/// Request parameters for the [`get_crypto_loans_income_history`] operation.
121///
122/// This struct holds all of the inputs you can pass when calling
123/// [`get_crypto_loans_income_history`](#method.get_crypto_loans_income_history).
124#[derive(Clone, Debug, Builder, Default)]
125#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
126pub struct GetCryptoLoansIncomeHistoryParams {
127    ///
128    /// The `asset` parameter.
129    ///
130    /// This field is **optional.
131    #[builder(setter(into), default)]
132    pub asset: Option<String>,
133    /// All types will be returned by default. Enum:`borrowIn` ,`collateralSpent`, `repayAmount`, `collateralReturn`(Collateral return after repayment), `addCollateral`, `removeCollateral`, `collateralReturnAfterLiquidation`
134    ///
135    /// This field is **optional.
136    #[builder(setter(into), default)]
137    pub r#type: Option<String>,
138    ///
139    /// The `start_time` parameter.
140    ///
141    /// This field is **optional.
142    #[builder(setter(into), default)]
143    pub start_time: Option<i64>,
144    ///
145    /// The `end_time` parameter.
146    ///
147    /// This field is **optional.
148    #[builder(setter(into), default)]
149    pub end_time: Option<i64>,
150    /// Default: 10; max: 100
151    ///
152    /// This field is **optional.
153    #[builder(setter(into), default)]
154    pub limit: Option<i64>,
155    ///
156    /// The `recv_window` parameter.
157    ///
158    /// This field is **optional.
159    #[builder(setter(into), default)]
160    pub recv_window: Option<i64>,
161}
162
163impl GetCryptoLoansIncomeHistoryParams {
164    /// Create a builder for [`get_crypto_loans_income_history`].
165    ///
166    #[must_use]
167    pub fn builder() -> GetCryptoLoansIncomeHistoryParamsBuilder {
168        GetCryptoLoansIncomeHistoryParamsBuilder::default()
169    }
170}
171/// Request parameters for the [`get_loan_borrow_history`] operation.
172///
173/// This struct holds all of the inputs you can pass when calling
174/// [`get_loan_borrow_history`](#method.get_loan_borrow_history).
175#[derive(Clone, Debug, Builder, Default)]
176#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
177pub struct GetLoanBorrowHistoryParams {
178    /// orderId in `POST /sapi/v1/loan/borrow`
179    ///
180    /// This field is **optional.
181    #[builder(setter(into), default)]
182    pub order_id: Option<i64>,
183    ///
184    /// The `loan_coin` parameter.
185    ///
186    /// This field is **optional.
187    #[builder(setter(into), default)]
188    pub loan_coin: Option<String>,
189    ///
190    /// The `collateral_coin` parameter.
191    ///
192    /// This field is **optional.
193    #[builder(setter(into), default)]
194    pub collateral_coin: Option<String>,
195    ///
196    /// The `start_time` parameter.
197    ///
198    /// This field is **optional.
199    #[builder(setter(into), default)]
200    pub start_time: Option<i64>,
201    ///
202    /// The `end_time` parameter.
203    ///
204    /// This field is **optional.
205    #[builder(setter(into), default)]
206    pub end_time: Option<i64>,
207    /// Current querying page. Start from 1; default: 1; max: 1000
208    ///
209    /// This field is **optional.
210    #[builder(setter(into), default)]
211    pub current: Option<i64>,
212    /// Default: 10; max: 100
213    ///
214    /// This field is **optional.
215    #[builder(setter(into), default)]
216    pub limit: Option<i64>,
217    ///
218    /// The `recv_window` parameter.
219    ///
220    /// This field is **optional.
221    #[builder(setter(into), default)]
222    pub recv_window: Option<i64>,
223}
224
225impl GetLoanBorrowHistoryParams {
226    /// Create a builder for [`get_loan_borrow_history`].
227    ///
228    #[must_use]
229    pub fn builder() -> GetLoanBorrowHistoryParamsBuilder {
230        GetLoanBorrowHistoryParamsBuilder::default()
231    }
232}
233/// Request parameters for the [`get_loan_ltv_adjustment_history`] operation.
234///
235/// This struct holds all of the inputs you can pass when calling
236/// [`get_loan_ltv_adjustment_history`](#method.get_loan_ltv_adjustment_history).
237#[derive(Clone, Debug, Builder, Default)]
238#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
239pub struct GetLoanLtvAdjustmentHistoryParams {
240    /// orderId in `POST /sapi/v1/loan/borrow`
241    ///
242    /// This field is **optional.
243    #[builder(setter(into), default)]
244    pub order_id: Option<i64>,
245    ///
246    /// The `loan_coin` parameter.
247    ///
248    /// This field is **optional.
249    #[builder(setter(into), default)]
250    pub loan_coin: Option<String>,
251    ///
252    /// The `collateral_coin` parameter.
253    ///
254    /// This field is **optional.
255    #[builder(setter(into), default)]
256    pub collateral_coin: Option<String>,
257    ///
258    /// The `start_time` parameter.
259    ///
260    /// This field is **optional.
261    #[builder(setter(into), default)]
262    pub start_time: Option<i64>,
263    ///
264    /// The `end_time` parameter.
265    ///
266    /// This field is **optional.
267    #[builder(setter(into), default)]
268    pub end_time: Option<i64>,
269    /// Current querying page. Start from 1; default: 1; max: 1000
270    ///
271    /// This field is **optional.
272    #[builder(setter(into), default)]
273    pub current: Option<i64>,
274    /// Default: 10; max: 100
275    ///
276    /// This field is **optional.
277    #[builder(setter(into), default)]
278    pub limit: Option<i64>,
279    ///
280    /// The `recv_window` parameter.
281    ///
282    /// This field is **optional.
283    #[builder(setter(into), default)]
284    pub recv_window: Option<i64>,
285}
286
287impl GetLoanLtvAdjustmentHistoryParams {
288    /// Create a builder for [`get_loan_ltv_adjustment_history`].
289    ///
290    #[must_use]
291    pub fn builder() -> GetLoanLtvAdjustmentHistoryParamsBuilder {
292        GetLoanLtvAdjustmentHistoryParamsBuilder::default()
293    }
294}
295/// Request parameters for the [`get_loan_repayment_history`] operation.
296///
297/// This struct holds all of the inputs you can pass when calling
298/// [`get_loan_repayment_history`](#method.get_loan_repayment_history).
299#[derive(Clone, Debug, Builder, Default)]
300#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
301pub struct GetLoanRepaymentHistoryParams {
302    /// orderId in `POST /sapi/v1/loan/borrow`
303    ///
304    /// This field is **optional.
305    #[builder(setter(into), default)]
306    pub order_id: Option<i64>,
307    ///
308    /// The `loan_coin` parameter.
309    ///
310    /// This field is **optional.
311    #[builder(setter(into), default)]
312    pub loan_coin: Option<String>,
313    ///
314    /// The `collateral_coin` parameter.
315    ///
316    /// This field is **optional.
317    #[builder(setter(into), default)]
318    pub collateral_coin: Option<String>,
319    ///
320    /// The `start_time` parameter.
321    ///
322    /// This field is **optional.
323    #[builder(setter(into), default)]
324    pub start_time: Option<i64>,
325    ///
326    /// The `end_time` parameter.
327    ///
328    /// This field is **optional.
329    #[builder(setter(into), default)]
330    pub end_time: Option<i64>,
331    /// Current querying page. Start from 1; default: 1; max: 1000
332    ///
333    /// This field is **optional.
334    #[builder(setter(into), default)]
335    pub current: Option<i64>,
336    /// Default: 10; max: 100
337    ///
338    /// This field is **optional.
339    #[builder(setter(into), default)]
340    pub limit: Option<i64>,
341    ///
342    /// The `recv_window` parameter.
343    ///
344    /// This field is **optional.
345    #[builder(setter(into), default)]
346    pub recv_window: Option<i64>,
347}
348
349impl GetLoanRepaymentHistoryParams {
350    /// Create a builder for [`get_loan_repayment_history`].
351    ///
352    #[must_use]
353    pub fn builder() -> GetLoanRepaymentHistoryParamsBuilder {
354        GetLoanRepaymentHistoryParamsBuilder::default()
355    }
356}
357
358#[async_trait]
359impl StableRateApi for StableRateApiClient {
360    async fn check_collateral_repay_rate_stable_rate(
361        &self,
362        params: CheckCollateralRepayRateStableRateParams,
363    ) -> anyhow::Result<RestApiResponse<models::CheckCollateralRepayRateStableRateResponse>> {
364        let CheckCollateralRepayRateStableRateParams {
365            loan_coin,
366            collateral_coin,
367            repay_amount,
368            recv_window,
369        } = params;
370
371        let mut query_params = BTreeMap::new();
372        let body_params = BTreeMap::new();
373
374        query_params.insert("loanCoin".to_string(), json!(loan_coin));
375
376        query_params.insert("collateralCoin".to_string(), json!(collateral_coin));
377
378        query_params.insert("repayAmount".to_string(), json!(repay_amount));
379
380        if let Some(rw) = recv_window {
381            query_params.insert("recvWindow".to_string(), json!(rw));
382        }
383
384        send_request::<models::CheckCollateralRepayRateStableRateResponse>(
385            &self.configuration,
386            "/sapi/v1/loan/repay/collateral/rate",
387            reqwest::Method::GET,
388            query_params,
389            body_params,
390            if HAS_TIME_UNIT {
391                self.configuration.time_unit
392            } else {
393                None
394            },
395            true,
396        )
397        .await
398    }
399
400    async fn get_crypto_loans_income_history(
401        &self,
402        params: GetCryptoLoansIncomeHistoryParams,
403    ) -> anyhow::Result<RestApiResponse<Vec<models::GetCryptoLoansIncomeHistoryResponseInner>>>
404    {
405        let GetCryptoLoansIncomeHistoryParams {
406            asset,
407            r#type,
408            start_time,
409            end_time,
410            limit,
411            recv_window,
412        } = params;
413
414        let mut query_params = BTreeMap::new();
415        let body_params = BTreeMap::new();
416
417        if let Some(rw) = asset {
418            query_params.insert("asset".to_string(), json!(rw));
419        }
420
421        if let Some(rw) = r#type {
422            query_params.insert("type".to_string(), json!(rw));
423        }
424
425        if let Some(rw) = start_time {
426            query_params.insert("startTime".to_string(), json!(rw));
427        }
428
429        if let Some(rw) = end_time {
430            query_params.insert("endTime".to_string(), json!(rw));
431        }
432
433        if let Some(rw) = limit {
434            query_params.insert("limit".to_string(), json!(rw));
435        }
436
437        if let Some(rw) = recv_window {
438            query_params.insert("recvWindow".to_string(), json!(rw));
439        }
440
441        send_request::<Vec<models::GetCryptoLoansIncomeHistoryResponseInner>>(
442            &self.configuration,
443            "/sapi/v1/loan/income",
444            reqwest::Method::GET,
445            query_params,
446            body_params,
447            if HAS_TIME_UNIT {
448                self.configuration.time_unit
449            } else {
450                None
451            },
452            true,
453        )
454        .await
455    }
456
457    async fn get_loan_borrow_history(
458        &self,
459        params: GetLoanBorrowHistoryParams,
460    ) -> anyhow::Result<RestApiResponse<models::GetLoanBorrowHistoryResponse>> {
461        let GetLoanBorrowHistoryParams {
462            order_id,
463            loan_coin,
464            collateral_coin,
465            start_time,
466            end_time,
467            current,
468            limit,
469            recv_window,
470        } = params;
471
472        let mut query_params = BTreeMap::new();
473        let body_params = BTreeMap::new();
474
475        if let Some(rw) = order_id {
476            query_params.insert("orderId".to_string(), json!(rw));
477        }
478
479        if let Some(rw) = loan_coin {
480            query_params.insert("loanCoin".to_string(), json!(rw));
481        }
482
483        if let Some(rw) = collateral_coin {
484            query_params.insert("collateralCoin".to_string(), json!(rw));
485        }
486
487        if let Some(rw) = start_time {
488            query_params.insert("startTime".to_string(), json!(rw));
489        }
490
491        if let Some(rw) = end_time {
492            query_params.insert("endTime".to_string(), json!(rw));
493        }
494
495        if let Some(rw) = current {
496            query_params.insert("current".to_string(), json!(rw));
497        }
498
499        if let Some(rw) = limit {
500            query_params.insert("limit".to_string(), json!(rw));
501        }
502
503        if let Some(rw) = recv_window {
504            query_params.insert("recvWindow".to_string(), json!(rw));
505        }
506
507        send_request::<models::GetLoanBorrowHistoryResponse>(
508            &self.configuration,
509            "/sapi/v1/loan/borrow/history",
510            reqwest::Method::GET,
511            query_params,
512            body_params,
513            if HAS_TIME_UNIT {
514                self.configuration.time_unit
515            } else {
516                None
517            },
518            true,
519        )
520        .await
521    }
522
523    async fn get_loan_ltv_adjustment_history(
524        &self,
525        params: GetLoanLtvAdjustmentHistoryParams,
526    ) -> anyhow::Result<RestApiResponse<models::GetLoanLtvAdjustmentHistoryResponse>> {
527        let GetLoanLtvAdjustmentHistoryParams {
528            order_id,
529            loan_coin,
530            collateral_coin,
531            start_time,
532            end_time,
533            current,
534            limit,
535            recv_window,
536        } = params;
537
538        let mut query_params = BTreeMap::new();
539        let body_params = BTreeMap::new();
540
541        if let Some(rw) = order_id {
542            query_params.insert("orderId".to_string(), json!(rw));
543        }
544
545        if let Some(rw) = loan_coin {
546            query_params.insert("loanCoin".to_string(), json!(rw));
547        }
548
549        if let Some(rw) = collateral_coin {
550            query_params.insert("collateralCoin".to_string(), json!(rw));
551        }
552
553        if let Some(rw) = start_time {
554            query_params.insert("startTime".to_string(), json!(rw));
555        }
556
557        if let Some(rw) = end_time {
558            query_params.insert("endTime".to_string(), json!(rw));
559        }
560
561        if let Some(rw) = current {
562            query_params.insert("current".to_string(), json!(rw));
563        }
564
565        if let Some(rw) = limit {
566            query_params.insert("limit".to_string(), json!(rw));
567        }
568
569        if let Some(rw) = recv_window {
570            query_params.insert("recvWindow".to_string(), json!(rw));
571        }
572
573        send_request::<models::GetLoanLtvAdjustmentHistoryResponse>(
574            &self.configuration,
575            "/sapi/v1/loan/ltv/adjustment/history",
576            reqwest::Method::GET,
577            query_params,
578            body_params,
579            if HAS_TIME_UNIT {
580                self.configuration.time_unit
581            } else {
582                None
583            },
584            true,
585        )
586        .await
587    }
588
589    async fn get_loan_repayment_history(
590        &self,
591        params: GetLoanRepaymentHistoryParams,
592    ) -> anyhow::Result<RestApiResponse<models::GetLoanRepaymentHistoryResponse>> {
593        let GetLoanRepaymentHistoryParams {
594            order_id,
595            loan_coin,
596            collateral_coin,
597            start_time,
598            end_time,
599            current,
600            limit,
601            recv_window,
602        } = params;
603
604        let mut query_params = BTreeMap::new();
605        let body_params = BTreeMap::new();
606
607        if let Some(rw) = order_id {
608            query_params.insert("orderId".to_string(), json!(rw));
609        }
610
611        if let Some(rw) = loan_coin {
612            query_params.insert("loanCoin".to_string(), json!(rw));
613        }
614
615        if let Some(rw) = collateral_coin {
616            query_params.insert("collateralCoin".to_string(), json!(rw));
617        }
618
619        if let Some(rw) = start_time {
620            query_params.insert("startTime".to_string(), json!(rw));
621        }
622
623        if let Some(rw) = end_time {
624            query_params.insert("endTime".to_string(), json!(rw));
625        }
626
627        if let Some(rw) = current {
628            query_params.insert("current".to_string(), json!(rw));
629        }
630
631        if let Some(rw) = limit {
632            query_params.insert("limit".to_string(), json!(rw));
633        }
634
635        if let Some(rw) = recv_window {
636            query_params.insert("recvWindow".to_string(), json!(rw));
637        }
638
639        send_request::<models::GetLoanRepaymentHistoryResponse>(
640            &self.configuration,
641            "/sapi/v1/loan/repay/history",
642            reqwest::Method::GET,
643            query_params,
644            body_params,
645            if HAS_TIME_UNIT {
646                self.configuration.time_unit
647            } else {
648                None
649            },
650            true,
651        )
652        .await
653    }
654}
655
656#[cfg(all(test, feature = "crypto_loan"))]
657mod tests {
658    use super::*;
659    use crate::TOKIO_SHARED_RT;
660    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
661    use async_trait::async_trait;
662    use std::collections::HashMap;
663
664    struct DummyRestApiResponse<T> {
665        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
666        status: u16,
667        headers: HashMap<String, String>,
668        rate_limits: Option<Vec<RestApiRateLimit>>,
669    }
670
671    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
672        fn from(dummy: DummyRestApiResponse<T>) -> Self {
673            Self {
674                data_fn: dummy.inner,
675                status: dummy.status,
676                headers: dummy.headers,
677                rate_limits: dummy.rate_limits,
678            }
679        }
680    }
681
682    struct MockStableRateApiClient {
683        force_error: bool,
684    }
685
686    #[async_trait]
687    impl StableRateApi for MockStableRateApiClient {
688        async fn check_collateral_repay_rate_stable_rate(
689            &self,
690            _params: CheckCollateralRepayRateStableRateParams,
691        ) -> anyhow::Result<RestApiResponse<models::CheckCollateralRepayRateStableRateResponse>>
692        {
693            if self.force_error {
694                return Err(ConnectorError::ConnectorClientError {
695                    msg: "ResponseError".to_string(),
696                    code: None,
697                }
698                .into());
699            }
700
701            let resp_json: Value = serde_json::from_str(r#"{"loanlCoin":"BUSD","collateralCoin":"BNB","repayAmount":"1000","rate":"300.36781234"}"#).unwrap();
702            let dummy_response: models::CheckCollateralRepayRateStableRateResponse =
703                serde_json::from_value(resp_json.clone())
704                    .expect("should parse into models::CheckCollateralRepayRateStableRateResponse");
705
706            let dummy = DummyRestApiResponse {
707                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
708                status: 200,
709                headers: HashMap::new(),
710                rate_limits: None,
711            };
712
713            Ok(dummy.into())
714        }
715
716        async fn get_crypto_loans_income_history(
717            &self,
718            _params: GetCryptoLoansIncomeHistoryParams,
719        ) -> anyhow::Result<RestApiResponse<Vec<models::GetCryptoLoansIncomeHistoryResponseInner>>>
720        {
721            if self.force_error {
722                return Err(ConnectorError::ConnectorClientError {
723                    msg: "ResponseError".to_string(),
724                    code: None,
725                }
726                .into());
727            }
728
729            let resp_json: Value = serde_json::from_str(r#"[{"asset":"BUSD","type":"borrowIn","amount":"100","timestamp":1633771139847,"tranId":"80423589583"},{"asset":"BUSD","type":"borrowIn","amount":"100","timestamp":1634638371496,"tranId":"81685123491"}]"#).unwrap();
730            let dummy_response: Vec<models::GetCryptoLoansIncomeHistoryResponseInner> =
731                serde_json::from_value(resp_json.clone()).expect(
732                    "should parse into Vec<models::GetCryptoLoansIncomeHistoryResponseInner>",
733                );
734
735            let dummy = DummyRestApiResponse {
736                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
737                status: 200,
738                headers: HashMap::new(),
739                rate_limits: None,
740            };
741
742            Ok(dummy.into())
743        }
744
745        async fn get_loan_borrow_history(
746            &self,
747            _params: GetLoanBorrowHistoryParams,
748        ) -> anyhow::Result<RestApiResponse<models::GetLoanBorrowHistoryResponse>> {
749            if self.force_error {
750                return Err(ConnectorError::ConnectorClientError {
751                    msg: "ResponseError".to_string(),
752                    code: None,
753                }
754                .into());
755            }
756
757            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"orderId":100000001,"loanCoin":"BUSD","initialLoanAmount":"10000","hourlyInterestRate":"0.000057","loanTerm":"7","collateralCoin":"BNB","initialCollateralAmount":"49.27565492","borrowTime":1575018510000,"status":"Repaid"}],"total":1}"#).unwrap();
758            let dummy_response: models::GetLoanBorrowHistoryResponse =
759                serde_json::from_value(resp_json.clone())
760                    .expect("should parse into models::GetLoanBorrowHistoryResponse");
761
762            let dummy = DummyRestApiResponse {
763                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
764                status: 200,
765                headers: HashMap::new(),
766                rate_limits: None,
767            };
768
769            Ok(dummy.into())
770        }
771
772        async fn get_loan_ltv_adjustment_history(
773            &self,
774            _params: GetLoanLtvAdjustmentHistoryParams,
775        ) -> anyhow::Result<RestApiResponse<models::GetLoanLtvAdjustmentHistoryResponse>> {
776            if self.force_error {
777                return Err(ConnectorError::ConnectorClientError {
778                    msg: "ResponseError".to_string(),
779                    code: None,
780                }
781                .into());
782            }
783
784            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","amount":"5.235","preLTV":"0.78","afterLTV":"0.56","adjustTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap();
785            let dummy_response: models::GetLoanLtvAdjustmentHistoryResponse =
786                serde_json::from_value(resp_json.clone())
787                    .expect("should parse into models::GetLoanLtvAdjustmentHistoryResponse");
788
789            let dummy = DummyRestApiResponse {
790                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
791                status: 200,
792                headers: HashMap::new(),
793                rate_limits: None,
794            };
795
796            Ok(dummy.into())
797        }
798
799        async fn get_loan_repayment_history(
800            &self,
801            _params: GetLoanRepaymentHistoryParams,
802        ) -> anyhow::Result<RestApiResponse<models::GetLoanRepaymentHistoryResponse>> {
803            if self.force_error {
804                return Err(ConnectorError::ConnectorClientError {
805                    msg: "ResponseError".to_string(),
806                    code: None,
807                }
808                .into());
809            }
810
811            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB","collateralUsed":"0","collateralReturn":"49.27565492","repayType":"1","repayStatus":"Repaid","repayTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap();
812            let dummy_response: models::GetLoanRepaymentHistoryResponse =
813                serde_json::from_value(resp_json.clone())
814                    .expect("should parse into models::GetLoanRepaymentHistoryResponse");
815
816            let dummy = DummyRestApiResponse {
817                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
818                status: 200,
819                headers: HashMap::new(),
820                rate_limits: None,
821            };
822
823            Ok(dummy.into())
824        }
825    }
826
827    #[test]
828    fn check_collateral_repay_rate_stable_rate_required_params_success() {
829        TOKIO_SHARED_RT.block_on(async {
830            let client = MockStableRateApiClient { force_error: false };
831
832            let params = CheckCollateralRepayRateStableRateParams::builder("loan_coin_example".to_string(),"collateral_coin_example".to_string(),dec!(1.0),).build().unwrap();
833
834            let resp_json: Value = serde_json::from_str(r#"{"loanlCoin":"BUSD","collateralCoin":"BNB","repayAmount":"1000","rate":"300.36781234"}"#).unwrap();
835            let expected_response : models::CheckCollateralRepayRateStableRateResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CheckCollateralRepayRateStableRateResponse");
836
837            let resp = client.check_collateral_repay_rate_stable_rate(params).await.expect("Expected a response");
838            let data_future = resp.data();
839            let actual_response = data_future.await.unwrap();
840            assert_eq!(actual_response, expected_response);
841        });
842    }
843
844    #[test]
845    fn check_collateral_repay_rate_stable_rate_optional_params_success() {
846        TOKIO_SHARED_RT.block_on(async {
847            let client = MockStableRateApiClient { force_error: false };
848
849            let params = CheckCollateralRepayRateStableRateParams::builder("loan_coin_example".to_string(),"collateral_coin_example".to_string(),dec!(1.0),).recv_window(5000).build().unwrap();
850
851            let resp_json: Value = serde_json::from_str(r#"{"loanlCoin":"BUSD","collateralCoin":"BNB","repayAmount":"1000","rate":"300.36781234"}"#).unwrap();
852            let expected_response : models::CheckCollateralRepayRateStableRateResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CheckCollateralRepayRateStableRateResponse");
853
854            let resp = client.check_collateral_repay_rate_stable_rate(params).await.expect("Expected a response");
855            let data_future = resp.data();
856            let actual_response = data_future.await.unwrap();
857            assert_eq!(actual_response, expected_response);
858        });
859    }
860
861    #[test]
862    fn check_collateral_repay_rate_stable_rate_response_error() {
863        TOKIO_SHARED_RT.block_on(async {
864            let client = MockStableRateApiClient { force_error: true };
865
866            let params = CheckCollateralRepayRateStableRateParams::builder(
867                "loan_coin_example".to_string(),
868                "collateral_coin_example".to_string(),
869                dec!(1.0),
870            )
871            .build()
872            .unwrap();
873
874            match client.check_collateral_repay_rate_stable_rate(params).await {
875                Ok(_) => panic!("Expected an error"),
876                Err(err) => {
877                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
878                }
879            }
880        });
881    }
882
883    #[test]
884    fn get_crypto_loans_income_history_required_params_success() {
885        TOKIO_SHARED_RT.block_on(async {
886            let client = MockStableRateApiClient { force_error: false };
887
888            let params = GetCryptoLoansIncomeHistoryParams::builder().build().unwrap();
889
890            let resp_json: Value = serde_json::from_str(r#"[{"asset":"BUSD","type":"borrowIn","amount":"100","timestamp":1633771139847,"tranId":"80423589583"},{"asset":"BUSD","type":"borrowIn","amount":"100","timestamp":1634638371496,"tranId":"81685123491"}]"#).unwrap();
891            let expected_response : Vec<models::GetCryptoLoansIncomeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetCryptoLoansIncomeHistoryResponseInner>");
892
893            let resp = client.get_crypto_loans_income_history(params).await.expect("Expected a response");
894            let data_future = resp.data();
895            let actual_response = data_future.await.unwrap();
896            assert_eq!(actual_response, expected_response);
897        });
898    }
899
900    #[test]
901    fn get_crypto_loans_income_history_optional_params_success() {
902        TOKIO_SHARED_RT.block_on(async {
903            let client = MockStableRateApiClient { force_error: false };
904
905            let params = GetCryptoLoansIncomeHistoryParams::builder().asset("asset_example".to_string()).r#type("0".to_string()).start_time(1623319461670).end_time(1641782889000).limit(10).recv_window(5000).build().unwrap();
906
907            let resp_json: Value = serde_json::from_str(r#"[{"asset":"BUSD","type":"borrowIn","amount":"100","timestamp":1633771139847,"tranId":"80423589583"},{"asset":"BUSD","type":"borrowIn","amount":"100","timestamp":1634638371496,"tranId":"81685123491"}]"#).unwrap();
908            let expected_response : Vec<models::GetCryptoLoansIncomeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetCryptoLoansIncomeHistoryResponseInner>");
909
910            let resp = client.get_crypto_loans_income_history(params).await.expect("Expected a response");
911            let data_future = resp.data();
912            let actual_response = data_future.await.unwrap();
913            assert_eq!(actual_response, expected_response);
914        });
915    }
916
917    #[test]
918    fn get_crypto_loans_income_history_response_error() {
919        TOKIO_SHARED_RT.block_on(async {
920            let client = MockStableRateApiClient { force_error: true };
921
922            let params = GetCryptoLoansIncomeHistoryParams::builder()
923                .build()
924                .unwrap();
925
926            match client.get_crypto_loans_income_history(params).await {
927                Ok(_) => panic!("Expected an error"),
928                Err(err) => {
929                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
930                }
931            }
932        });
933    }
934
935    #[test]
936    fn get_loan_borrow_history_required_params_success() {
937        TOKIO_SHARED_RT.block_on(async {
938            let client = MockStableRateApiClient { force_error: false };
939
940            let params = GetLoanBorrowHistoryParams::builder().build().unwrap();
941
942            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"orderId":100000001,"loanCoin":"BUSD","initialLoanAmount":"10000","hourlyInterestRate":"0.000057","loanTerm":"7","collateralCoin":"BNB","initialCollateralAmount":"49.27565492","borrowTime":1575018510000,"status":"Repaid"}],"total":1}"#).unwrap();
943            let expected_response : models::GetLoanBorrowHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLoanBorrowHistoryResponse");
944
945            let resp = client.get_loan_borrow_history(params).await.expect("Expected a response");
946            let data_future = resp.data();
947            let actual_response = data_future.await.unwrap();
948            assert_eq!(actual_response, expected_response);
949        });
950    }
951
952    #[test]
953    fn get_loan_borrow_history_optional_params_success() {
954        TOKIO_SHARED_RT.block_on(async {
955            let client = MockStableRateApiClient { force_error: false };
956
957            let params = GetLoanBorrowHistoryParams::builder().order_id(1).loan_coin("loan_coin_example".to_string()).collateral_coin("collateral_coin_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
958
959            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"orderId":100000001,"loanCoin":"BUSD","initialLoanAmount":"10000","hourlyInterestRate":"0.000057","loanTerm":"7","collateralCoin":"BNB","initialCollateralAmount":"49.27565492","borrowTime":1575018510000,"status":"Repaid"}],"total":1}"#).unwrap();
960            let expected_response : models::GetLoanBorrowHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLoanBorrowHistoryResponse");
961
962            let resp = client.get_loan_borrow_history(params).await.expect("Expected a response");
963            let data_future = resp.data();
964            let actual_response = data_future.await.unwrap();
965            assert_eq!(actual_response, expected_response);
966        });
967    }
968
969    #[test]
970    fn get_loan_borrow_history_response_error() {
971        TOKIO_SHARED_RT.block_on(async {
972            let client = MockStableRateApiClient { force_error: true };
973
974            let params = GetLoanBorrowHistoryParams::builder().build().unwrap();
975
976            match client.get_loan_borrow_history(params).await {
977                Ok(_) => panic!("Expected an error"),
978                Err(err) => {
979                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
980                }
981            }
982        });
983    }
984
985    #[test]
986    fn get_loan_ltv_adjustment_history_required_params_success() {
987        TOKIO_SHARED_RT.block_on(async {
988            let client = MockStableRateApiClient { force_error: false };
989
990            let params = GetLoanLtvAdjustmentHistoryParams::builder().build().unwrap();
991
992            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","amount":"5.235","preLTV":"0.78","afterLTV":"0.56","adjustTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap();
993            let expected_response : models::GetLoanLtvAdjustmentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLoanLtvAdjustmentHistoryResponse");
994
995            let resp = client.get_loan_ltv_adjustment_history(params).await.expect("Expected a response");
996            let data_future = resp.data();
997            let actual_response = data_future.await.unwrap();
998            assert_eq!(actual_response, expected_response);
999        });
1000    }
1001
1002    #[test]
1003    fn get_loan_ltv_adjustment_history_optional_params_success() {
1004        TOKIO_SHARED_RT.block_on(async {
1005            let client = MockStableRateApiClient { force_error: false };
1006
1007            let params = GetLoanLtvAdjustmentHistoryParams::builder().order_id(1).loan_coin("loan_coin_example".to_string()).collateral_coin("collateral_coin_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
1008
1009            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","collateralCoin":"BNB","direction":"ADDITIONAL","amount":"5.235","preLTV":"0.78","afterLTV":"0.56","adjustTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap();
1010            let expected_response : models::GetLoanLtvAdjustmentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLoanLtvAdjustmentHistoryResponse");
1011
1012            let resp = client.get_loan_ltv_adjustment_history(params).await.expect("Expected a response");
1013            let data_future = resp.data();
1014            let actual_response = data_future.await.unwrap();
1015            assert_eq!(actual_response, expected_response);
1016        });
1017    }
1018
1019    #[test]
1020    fn get_loan_ltv_adjustment_history_response_error() {
1021        TOKIO_SHARED_RT.block_on(async {
1022            let client = MockStableRateApiClient { force_error: true };
1023
1024            let params = GetLoanLtvAdjustmentHistoryParams::builder()
1025                .build()
1026                .unwrap();
1027
1028            match client.get_loan_ltv_adjustment_history(params).await {
1029                Ok(_) => panic!("Expected an error"),
1030                Err(err) => {
1031                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1032                }
1033            }
1034        });
1035    }
1036
1037    #[test]
1038    fn get_loan_repayment_history_required_params_success() {
1039        TOKIO_SHARED_RT.block_on(async {
1040            let client = MockStableRateApiClient { force_error: false };
1041
1042            let params = GetLoanRepaymentHistoryParams::builder().build().unwrap();
1043
1044            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB","collateralUsed":"0","collateralReturn":"49.27565492","repayType":"1","repayStatus":"Repaid","repayTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap();
1045            let expected_response : models::GetLoanRepaymentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLoanRepaymentHistoryResponse");
1046
1047            let resp = client.get_loan_repayment_history(params).await.expect("Expected a response");
1048            let data_future = resp.data();
1049            let actual_response = data_future.await.unwrap();
1050            assert_eq!(actual_response, expected_response);
1051        });
1052    }
1053
1054    #[test]
1055    fn get_loan_repayment_history_optional_params_success() {
1056        TOKIO_SHARED_RT.block_on(async {
1057            let client = MockStableRateApiClient { force_error: false };
1058
1059            let params = GetLoanRepaymentHistoryParams::builder().order_id(1).loan_coin("loan_coin_example".to_string()).collateral_coin("collateral_coin_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).limit(10).recv_window(5000).build().unwrap();
1060
1061            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"loanCoin":"BUSD","repayAmount":"10000","collateralCoin":"BNB","collateralUsed":"0","collateralReturn":"49.27565492","repayType":"1","repayStatus":"Repaid","repayTime":1575018510000,"orderId":756783308056935400}],"total":1}"#).unwrap();
1062            let expected_response : models::GetLoanRepaymentHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLoanRepaymentHistoryResponse");
1063
1064            let resp = client.get_loan_repayment_history(params).await.expect("Expected a response");
1065            let data_future = resp.data();
1066            let actual_response = data_future.await.unwrap();
1067            assert_eq!(actual_response, expected_response);
1068        });
1069    }
1070
1071    #[test]
1072    fn get_loan_repayment_history_response_error() {
1073        TOKIO_SHARED_RT.block_on(async {
1074            let client = MockStableRateApiClient { force_error: true };
1075
1076            let params = GetLoanRepaymentHistoryParams::builder().build().unwrap();
1077
1078            match client.get_loan_repayment_history(params).await {
1079                Ok(_) => panic!("Expected an error"),
1080                Err(err) => {
1081                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1082                }
1083            }
1084        });
1085    }
1086}