/*
 * Binance Simple Earn REST API
 *
 * OpenAPI Specification for the Binance Simple Earn REST API
 *
 * The version of the OpenAPI document: 1.0.0
 *
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

#![allow(unused_imports)]
use async_trait::async_trait;
use derive_builder::Builder;
use reqwest;
use rust_decimal::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use std::collections::BTreeMap;

use crate::common::{
    config::ConfigurationRestApi,
    models::{ParamBuildError, RestApiResponse},
    utils::send_request,
};
use crate::simple_earn::rest_api::models;

const HAS_TIME_UNIT: bool = false;

#[async_trait]
pub trait FlexibleLockedApi: Send + Sync {
    async fn get_collateral_record(
        &self,
        params: GetCollateralRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetCollateralRecordResponse>>;
    async fn get_flexible_personal_left_quota(
        &self,
        params: GetFlexiblePersonalLeftQuotaParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexiblePersonalLeftQuotaResponse>>;
    async fn get_flexible_product_position(
        &self,
        params: GetFlexibleProductPositionParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleProductPositionResponse>>;
    async fn get_flexible_redemption_record(
        &self,
        params: GetFlexibleRedemptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleRedemptionRecordResponse>>;
    async fn get_flexible_rewards_history(
        &self,
        params: GetFlexibleRewardsHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleRewardsHistoryResponse>>;
    async fn get_flexible_subscription_preview(
        &self,
        params: GetFlexibleSubscriptionPreviewParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleSubscriptionPreviewResponse>>;
    async fn get_flexible_subscription_record(
        &self,
        params: GetFlexibleSubscriptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleSubscriptionRecordResponse>>;
    async fn get_locked_personal_left_quota(
        &self,
        params: GetLockedPersonalLeftQuotaParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedPersonalLeftQuotaResponse>>;
    async fn get_locked_product_position(
        &self,
        params: GetLockedProductPositionParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedProductPositionResponse>>;
    async fn get_locked_redemption_record(
        &self,
        params: GetLockedRedemptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedRedemptionRecordResponse>>;
    async fn get_locked_rewards_history(
        &self,
        params: GetLockedRewardsHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedRewardsHistoryResponse>>;
    async fn get_locked_subscription_preview(
        &self,
        params: GetLockedSubscriptionPreviewParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::GetLockedSubscriptionPreviewResponseInner>>>;
    async fn get_locked_subscription_record(
        &self,
        params: GetLockedSubscriptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedSubscriptionRecordResponse>>;
    async fn get_rate_history(
        &self,
        params: GetRateHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetRateHistoryResponse>>;
    async fn get_simple_earn_flexible_product_list(
        &self,
        params: GetSimpleEarnFlexibleProductListParams,
    ) -> anyhow::Result<RestApiResponse<models::GetSimpleEarnFlexibleProductListResponse>>;
    async fn get_simple_earn_locked_product_list(
        &self,
        params: GetSimpleEarnLockedProductListParams,
    ) -> anyhow::Result<RestApiResponse<models::GetSimpleEarnLockedProductListResponse>>;
    async fn redeem_flexible_product(
        &self,
        params: RedeemFlexibleProductParams,
    ) -> anyhow::Result<RestApiResponse<models::RedeemFlexibleProductResponse>>;
    async fn redeem_locked_product(
        &self,
        params: RedeemLockedProductParams,
    ) -> anyhow::Result<RestApiResponse<models::RedeemLockedProductResponse>>;
    async fn set_flexible_auto_subscribe(
        &self,
        params: SetFlexibleAutoSubscribeParams,
    ) -> anyhow::Result<RestApiResponse<models::SetFlexibleAutoSubscribeResponse>>;
    async fn set_locked_auto_subscribe(
        &self,
        params: SetLockedAutoSubscribeParams,
    ) -> anyhow::Result<RestApiResponse<models::SetLockedAutoSubscribeResponse>>;
    async fn set_locked_product_redeem_option(
        &self,
        params: SetLockedProductRedeemOptionParams,
    ) -> anyhow::Result<RestApiResponse<models::SetLockedProductRedeemOptionResponse>>;
    async fn simple_account(
        &self,
        params: SimpleAccountParams,
    ) -> anyhow::Result<RestApiResponse<models::SimpleAccountResponse>>;
    async fn subscribe_flexible_product(
        &self,
        params: SubscribeFlexibleProductParams,
    ) -> anyhow::Result<RestApiResponse<models::SubscribeFlexibleProductResponse>>;
    async fn subscribe_locked_product(
        &self,
        params: SubscribeLockedProductParams,
    ) -> anyhow::Result<RestApiResponse<models::SubscribeLockedProductResponse>>;
}

#[derive(Debug, Clone)]
pub struct FlexibleLockedApiClient {
    configuration: ConfigurationRestApi,
}

impl FlexibleLockedApiClient {
    pub fn new(configuration: ConfigurationRestApi) -> Self {
        Self { configuration }
    }
}

/// Request parameters for the [`get_collateral_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_collateral_record`](#method.get_collateral_record).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetCollateralRecordParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub product_id: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetCollateralRecordParams {
    /// Create a builder for [`get_collateral_record`].
    ///
    #[must_use]
    pub fn builder() -> GetCollateralRecordParamsBuilder {
        GetCollateralRecordParamsBuilder::default()
    }
}
/// Request parameters for the [`get_flexible_personal_left_quota`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_flexible_personal_left_quota`](#method.get_flexible_personal_left_quota).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetFlexiblePersonalLeftQuotaParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub product_id: String,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetFlexiblePersonalLeftQuotaParams {
    /// Create a builder for [`get_flexible_personal_left_quota`].
    ///
    /// Required parameters:
    ///
    /// * `product_id` — String
    ///
    #[must_use]
    pub fn builder(product_id: String) -> GetFlexiblePersonalLeftQuotaParamsBuilder {
        GetFlexiblePersonalLeftQuotaParamsBuilder::default().product_id(product_id)
    }
}
/// Request parameters for the [`get_flexible_product_position`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_flexible_product_position`](#method.get_flexible_product_position).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetFlexibleProductPositionParams {
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub product_id: Option<String>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetFlexibleProductPositionParams {
    /// Create a builder for [`get_flexible_product_position`].
    ///
    #[must_use]
    pub fn builder() -> GetFlexibleProductPositionParamsBuilder {
        GetFlexibleProductPositionParamsBuilder::default()
    }
}
/// Request parameters for the [`get_flexible_redemption_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_flexible_redemption_record`](#method.get_flexible_redemption_record).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetFlexibleRedemptionRecordParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub product_id: Option<String>,
    ///
    /// The `redeem_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub redeem_id: Option<String>,
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetFlexibleRedemptionRecordParams {
    /// Create a builder for [`get_flexible_redemption_record`].
    ///
    #[must_use]
    pub fn builder() -> GetFlexibleRedemptionRecordParamsBuilder {
        GetFlexibleRedemptionRecordParamsBuilder::default()
    }
}
/// Request parameters for the [`get_flexible_rewards_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_flexible_rewards_history`](#method.get_flexible_rewards_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetFlexibleRewardsHistoryParams {
    /// FAST or STANDARD, defaults to STANDARD
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub r#type: String,
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub product_id: Option<String>,
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetFlexibleRewardsHistoryParams {
    /// Create a builder for [`get_flexible_rewards_history`].
    ///
    /// Required parameters:
    ///
    /// * `r#type` — FAST or STANDARD, defaults to STANDARD
    ///
    #[must_use]
    pub fn builder(r#type: String) -> GetFlexibleRewardsHistoryParamsBuilder {
        GetFlexibleRewardsHistoryParamsBuilder::default().r#type(r#type)
    }
}
/// Request parameters for the [`get_flexible_subscription_preview`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_flexible_subscription_preview`](#method.get_flexible_subscription_preview).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetFlexibleSubscriptionPreviewParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub product_id: String,
    /// Amount
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub amount: rust_decimal::Decimal,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetFlexibleSubscriptionPreviewParams {
    /// Create a builder for [`get_flexible_subscription_preview`].
    ///
    /// Required parameters:
    ///
    /// * `product_id` — String
    /// * `amount` — Amount
    ///
    #[must_use]
    pub fn builder(
        product_id: String,
        amount: rust_decimal::Decimal,
    ) -> GetFlexibleSubscriptionPreviewParamsBuilder {
        GetFlexibleSubscriptionPreviewParamsBuilder::default()
            .product_id(product_id)
            .amount(amount)
    }
}
/// Request parameters for the [`get_flexible_subscription_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_flexible_subscription_record`](#method.get_flexible_subscription_record).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetFlexibleSubscriptionRecordParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub product_id: Option<String>,
    ///
    /// The `purchase_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub purchase_id: Option<String>,
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetFlexibleSubscriptionRecordParams {
    /// Create a builder for [`get_flexible_subscription_record`].
    ///
    #[must_use]
    pub fn builder() -> GetFlexibleSubscriptionRecordParamsBuilder {
        GetFlexibleSubscriptionRecordParamsBuilder::default()
    }
}
/// Request parameters for the [`get_locked_personal_left_quota`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_locked_personal_left_quota`](#method.get_locked_personal_left_quota).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetLockedPersonalLeftQuotaParams {
    ///
    /// The `project_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub project_id: String,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetLockedPersonalLeftQuotaParams {
    /// Create a builder for [`get_locked_personal_left_quota`].
    ///
    /// Required parameters:
    ///
    /// * `project_id` — String
    ///
    #[must_use]
    pub fn builder(project_id: String) -> GetLockedPersonalLeftQuotaParamsBuilder {
        GetLockedPersonalLeftQuotaParamsBuilder::default().project_id(project_id)
    }
}
/// Request parameters for the [`get_locked_product_position`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_locked_product_position`](#method.get_locked_product_position).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetLockedProductPositionParams {
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `position_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub position_id: Option<i64>,
    ///
    /// The `project_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub project_id: Option<String>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetLockedProductPositionParams {
    /// Create a builder for [`get_locked_product_position`].
    ///
    #[must_use]
    pub fn builder() -> GetLockedProductPositionParamsBuilder {
        GetLockedProductPositionParamsBuilder::default()
    }
}
/// Request parameters for the [`get_locked_redemption_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_locked_redemption_record`](#method.get_locked_redemption_record).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetLockedRedemptionRecordParams {
    ///
    /// The `position_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub position_id: Option<i64>,
    ///
    /// The `redeem_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub redeem_id: Option<String>,
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetLockedRedemptionRecordParams {
    /// Create a builder for [`get_locked_redemption_record`].
    ///
    #[must_use]
    pub fn builder() -> GetLockedRedemptionRecordParamsBuilder {
        GetLockedRedemptionRecordParamsBuilder::default()
    }
}
/// Request parameters for the [`get_locked_rewards_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_locked_rewards_history`](#method.get_locked_rewards_history).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetLockedRewardsHistoryParams {
    ///
    /// The `position_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub position_id: Option<i64>,
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetLockedRewardsHistoryParams {
    /// Create a builder for [`get_locked_rewards_history`].
    ///
    #[must_use]
    pub fn builder() -> GetLockedRewardsHistoryParamsBuilder {
        GetLockedRewardsHistoryParamsBuilder::default()
    }
}
/// Request parameters for the [`get_locked_subscription_preview`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_locked_subscription_preview`](#method.get_locked_subscription_preview).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetLockedSubscriptionPreviewParams {
    ///
    /// The `project_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub project_id: String,
    /// Amount
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub amount: rust_decimal::Decimal,
    /// true or false, default true.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub auto_subscribe: Option<bool>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetLockedSubscriptionPreviewParams {
    /// Create a builder for [`get_locked_subscription_preview`].
    ///
    /// Required parameters:
    ///
    /// * `project_id` — String
    /// * `amount` — Amount
    ///
    #[must_use]
    pub fn builder(
        project_id: String,
        amount: rust_decimal::Decimal,
    ) -> GetLockedSubscriptionPreviewParamsBuilder {
        GetLockedSubscriptionPreviewParamsBuilder::default()
            .project_id(project_id)
            .amount(amount)
    }
}
/// Request parameters for the [`get_locked_subscription_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_locked_subscription_record`](#method.get_locked_subscription_record).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetLockedSubscriptionRecordParams {
    ///
    /// The `purchase_id` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub purchase_id: Option<String>,
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetLockedSubscriptionRecordParams {
    /// Create a builder for [`get_locked_subscription_record`].
    ///
    #[must_use]
    pub fn builder() -> GetLockedSubscriptionRecordParamsBuilder {
        GetLockedSubscriptionRecordParamsBuilder::default()
    }
}
/// Request parameters for the [`get_rate_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_rate_history`](#method.get_rate_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetRateHistoryParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub product_id: String,
    /// "DAY","YEAR",default"DAY"
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub apr_period: Option<String>,
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetRateHistoryParams {
    /// Create a builder for [`get_rate_history`].
    ///
    /// Required parameters:
    ///
    /// * `product_id` — String
    ///
    #[must_use]
    pub fn builder(product_id: String) -> GetRateHistoryParamsBuilder {
        GetRateHistoryParamsBuilder::default().product_id(product_id)
    }
}
/// Request parameters for the [`get_simple_earn_flexible_product_list`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_simple_earn_flexible_product_list`](#method.get_simple_earn_flexible_product_list).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetSimpleEarnFlexibleProductListParams {
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetSimpleEarnFlexibleProductListParams {
    /// Create a builder for [`get_simple_earn_flexible_product_list`].
    ///
    #[must_use]
    pub fn builder() -> GetSimpleEarnFlexibleProductListParamsBuilder {
        GetSimpleEarnFlexibleProductListParamsBuilder::default()
    }
}
/// Request parameters for the [`get_simple_earn_locked_product_list`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_simple_earn_locked_product_list`](#method.get_simple_earn_locked_product_list).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetSimpleEarnLockedProductListParams {
    /// USDC or USDT
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    /// Currently querying page. Starts from 1. Default: 1
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub current: Option<i64>,
    /// Number of results per page. Default: 10, Max: 100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetSimpleEarnLockedProductListParams {
    /// Create a builder for [`get_simple_earn_locked_product_list`].
    ///
    #[must_use]
    pub fn builder() -> GetSimpleEarnLockedProductListParamsBuilder {
        GetSimpleEarnLockedProductListParamsBuilder::default()
    }
}
/// Request parameters for the [`redeem_flexible_product`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`redeem_flexible_product`](#method.redeem_flexible_product).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct RedeemFlexibleProductParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub product_id: String,
    /// true or false, default to false
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub redeem_all: Option<bool>,
    /// if redeemAll is false, amount is mandatory
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub amount: Option<rust_decimal::Decimal>,
    /// `SPOT`,`FUND`, default `SPOT`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub dest_account: Option<String>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl RedeemFlexibleProductParams {
    /// Create a builder for [`redeem_flexible_product`].
    ///
    /// Required parameters:
    ///
    /// * `product_id` — String
    ///
    #[must_use]
    pub fn builder(product_id: String) -> RedeemFlexibleProductParamsBuilder {
        RedeemFlexibleProductParamsBuilder::default().product_id(product_id)
    }
}
/// Request parameters for the [`redeem_locked_product`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`redeem_locked_product`](#method.redeem_locked_product).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct RedeemLockedProductParams {
    ///
    /// The `position_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub position_id: String,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl RedeemLockedProductParams {
    /// Create a builder for [`redeem_locked_product`].
    ///
    /// Required parameters:
    ///
    /// * `position_id` — String
    ///
    #[must_use]
    pub fn builder(position_id: String) -> RedeemLockedProductParamsBuilder {
        RedeemLockedProductParamsBuilder::default().position_id(position_id)
    }
}
/// Request parameters for the [`set_flexible_auto_subscribe`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`set_flexible_auto_subscribe`](#method.set_flexible_auto_subscribe).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct SetFlexibleAutoSubscribeParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub product_id: String,
    /// true or false
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub auto_subscribe: bool,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl SetFlexibleAutoSubscribeParams {
    /// Create a builder for [`set_flexible_auto_subscribe`].
    ///
    /// Required parameters:
    ///
    /// * `product_id` — String
    /// * `auto_subscribe` — true or false
    ///
    #[must_use]
    pub fn builder(
        product_id: String,
        auto_subscribe: bool,
    ) -> SetFlexibleAutoSubscribeParamsBuilder {
        SetFlexibleAutoSubscribeParamsBuilder::default()
            .product_id(product_id)
            .auto_subscribe(auto_subscribe)
    }
}
/// Request parameters for the [`set_locked_auto_subscribe`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`set_locked_auto_subscribe`](#method.set_locked_auto_subscribe).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct SetLockedAutoSubscribeParams {
    ///
    /// The `position_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub position_id: String,
    /// true or false
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub auto_subscribe: bool,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl SetLockedAutoSubscribeParams {
    /// Create a builder for [`set_locked_auto_subscribe`].
    ///
    /// Required parameters:
    ///
    /// * `position_id` — String
    /// * `auto_subscribe` — true or false
    ///
    #[must_use]
    pub fn builder(
        position_id: String,
        auto_subscribe: bool,
    ) -> SetLockedAutoSubscribeParamsBuilder {
        SetLockedAutoSubscribeParamsBuilder::default()
            .position_id(position_id)
            .auto_subscribe(auto_subscribe)
    }
}
/// Request parameters for the [`set_locked_product_redeem_option`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`set_locked_product_redeem_option`](#method.set_locked_product_redeem_option).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct SetLockedProductRedeemOptionParams {
    ///
    /// The `position_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub position_id: String,
    /// `SPOT`,'FLEXIBLE'
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub redeem_to: String,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl SetLockedProductRedeemOptionParams {
    /// Create a builder for [`set_locked_product_redeem_option`].
    ///
    /// Required parameters:
    ///
    /// * `position_id` — String
    /// * `redeem_to` — `SPOT`,'FLEXIBLE'
    ///
    #[must_use]
    pub fn builder(
        position_id: String,
        redeem_to: String,
    ) -> SetLockedProductRedeemOptionParamsBuilder {
        SetLockedProductRedeemOptionParamsBuilder::default()
            .position_id(position_id)
            .redeem_to(redeem_to)
    }
}
/// Request parameters for the [`simple_account`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`simple_account`](#method.simple_account).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct SimpleAccountParams {
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl SimpleAccountParams {
    /// Create a builder for [`simple_account`].
    ///
    #[must_use]
    pub fn builder() -> SimpleAccountParamsBuilder {
        SimpleAccountParamsBuilder::default()
    }
}
/// Request parameters for the [`subscribe_flexible_product`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`subscribe_flexible_product`](#method.subscribe_flexible_product).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct SubscribeFlexibleProductParams {
    ///
    /// The `product_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub product_id: String,
    /// Amount
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub amount: rust_decimal::Decimal,
    /// true or false, default true.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub auto_subscribe: Option<bool>,
    /// `SPOT`,`FUND`,`ALL`, default `SPOT`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub source_account: Option<String>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl SubscribeFlexibleProductParams {
    /// Create a builder for [`subscribe_flexible_product`].
    ///
    /// Required parameters:
    ///
    /// * `product_id` — String
    /// * `amount` — Amount
    ///
    #[must_use]
    pub fn builder(
        product_id: String,
        amount: rust_decimal::Decimal,
    ) -> SubscribeFlexibleProductParamsBuilder {
        SubscribeFlexibleProductParamsBuilder::default()
            .product_id(product_id)
            .amount(amount)
    }
}
/// Request parameters for the [`subscribe_locked_product`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`subscribe_locked_product`](#method.subscribe_locked_product).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct SubscribeLockedProductParams {
    ///
    /// The `project_id` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub project_id: String,
    /// Amount
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub amount: rust_decimal::Decimal,
    /// true or false, default true.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub auto_subscribe: Option<bool>,
    /// `SPOT`,`FUND`,`ALL`, default `SPOT`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub source_account: Option<String>,
    /// `SPOT`,`FLEXIBLE`, default `SPOT`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub redeem_to: Option<String>,
    /// The value cannot be greater than 60000 (ms)
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl SubscribeLockedProductParams {
    /// Create a builder for [`subscribe_locked_product`].
    ///
    /// Required parameters:
    ///
    /// * `project_id` — String
    /// * `amount` — Amount
    ///
    #[must_use]
    pub fn builder(
        project_id: String,
        amount: rust_decimal::Decimal,
    ) -> SubscribeLockedProductParamsBuilder {
        SubscribeLockedProductParamsBuilder::default()
            .project_id(project_id)
            .amount(amount)
    }
}

#[async_trait]
impl FlexibleLockedApi for FlexibleLockedApiClient {
    async fn get_collateral_record(
        &self,
        params: GetCollateralRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetCollateralRecordResponse>> {
        let GetCollateralRecordParams {
            product_id,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = product_id {
            query_params.insert("productId".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetCollateralRecordResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/history/collateralRecord",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_flexible_personal_left_quota(
        &self,
        params: GetFlexiblePersonalLeftQuotaParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexiblePersonalLeftQuotaResponse>> {
        let GetFlexiblePersonalLeftQuotaParams {
            product_id,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("productId".to_string(), json!(product_id));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetFlexiblePersonalLeftQuotaResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/personalLeftQuota",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_flexible_product_position(
        &self,
        params: GetFlexibleProductPositionParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleProductPositionResponse>> {
        let GetFlexibleProductPositionParams {
            asset,
            product_id,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = product_id {
            query_params.insert("productId".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetFlexibleProductPositionResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/position",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_flexible_redemption_record(
        &self,
        params: GetFlexibleRedemptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleRedemptionRecordResponse>> {
        let GetFlexibleRedemptionRecordParams {
            product_id,
            redeem_id,
            asset,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = product_id {
            query_params.insert("productId".to_string(), json!(rw));
        }

        if let Some(rw) = redeem_id {
            query_params.insert("redeemId".to_string(), json!(rw));
        }

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetFlexibleRedemptionRecordResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/history/redemptionRecord",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_flexible_rewards_history(
        &self,
        params: GetFlexibleRewardsHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleRewardsHistoryResponse>> {
        let GetFlexibleRewardsHistoryParams {
            r#type,
            product_id,
            asset,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = product_id {
            query_params.insert("productId".to_string(), json!(rw));
        }

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        query_params.insert("type".to_string(), json!(r#type));

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetFlexibleRewardsHistoryResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/history/rewardsRecord",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_flexible_subscription_preview(
        &self,
        params: GetFlexibleSubscriptionPreviewParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleSubscriptionPreviewResponse>> {
        let GetFlexibleSubscriptionPreviewParams {
            product_id,
            amount,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("productId".to_string(), json!(product_id));

        query_params.insert("amount".to_string(), json!(amount));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetFlexibleSubscriptionPreviewResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/subscriptionPreview",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_flexible_subscription_record(
        &self,
        params: GetFlexibleSubscriptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetFlexibleSubscriptionRecordResponse>> {
        let GetFlexibleSubscriptionRecordParams {
            product_id,
            purchase_id,
            asset,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = product_id {
            query_params.insert("productId".to_string(), json!(rw));
        }

        if let Some(rw) = purchase_id {
            query_params.insert("purchaseId".to_string(), json!(rw));
        }

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetFlexibleSubscriptionRecordResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/history/subscriptionRecord",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_locked_personal_left_quota(
        &self,
        params: GetLockedPersonalLeftQuotaParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedPersonalLeftQuotaResponse>> {
        let GetLockedPersonalLeftQuotaParams {
            project_id,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("projectId".to_string(), json!(project_id));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetLockedPersonalLeftQuotaResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/personalLeftQuota",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_locked_product_position(
        &self,
        params: GetLockedProductPositionParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedProductPositionResponse>> {
        let GetLockedProductPositionParams {
            asset,
            position_id,
            project_id,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = position_id {
            query_params.insert("positionId".to_string(), json!(rw));
        }

        if let Some(rw) = project_id {
            query_params.insert("projectId".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetLockedProductPositionResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/position",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_locked_redemption_record(
        &self,
        params: GetLockedRedemptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedRedemptionRecordResponse>> {
        let GetLockedRedemptionRecordParams {
            position_id,
            redeem_id,
            asset,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = position_id {
            query_params.insert("positionId".to_string(), json!(rw));
        }

        if let Some(rw) = redeem_id {
            query_params.insert("redeemId".to_string(), json!(rw));
        }

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetLockedRedemptionRecordResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/history/redemptionRecord",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_locked_rewards_history(
        &self,
        params: GetLockedRewardsHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedRewardsHistoryResponse>> {
        let GetLockedRewardsHistoryParams {
            position_id,
            asset,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = position_id {
            query_params.insert("positionId".to_string(), json!(rw));
        }

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetLockedRewardsHistoryResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/history/rewardsRecord",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_locked_subscription_preview(
        &self,
        params: GetLockedSubscriptionPreviewParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::GetLockedSubscriptionPreviewResponseInner>>>
    {
        let GetLockedSubscriptionPreviewParams {
            project_id,
            amount,
            auto_subscribe,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("projectId".to_string(), json!(project_id));

        query_params.insert("amount".to_string(), json!(amount));

        if let Some(rw) = auto_subscribe {
            query_params.insert("autoSubscribe".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<Vec<models::GetLockedSubscriptionPreviewResponseInner>>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/subscriptionPreview",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_locked_subscription_record(
        &self,
        params: GetLockedSubscriptionRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::GetLockedSubscriptionRecordResponse>> {
        let GetLockedSubscriptionRecordParams {
            purchase_id,
            asset,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = purchase_id {
            query_params.insert("purchaseId".to_string(), json!(rw));
        }

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetLockedSubscriptionRecordResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/history/subscriptionRecord",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_rate_history(
        &self,
        params: GetRateHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetRateHistoryResponse>> {
        let GetRateHistoryParams {
            product_id,
            apr_period,
            start_time,
            end_time,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("productId".to_string(), json!(product_id));

        if let Some(rw) = apr_period {
            query_params.insert("aprPeriod".to_string(), json!(rw));
        }

        if let Some(rw) = start_time {
            query_params.insert("startTime".to_string(), json!(rw));
        }

        if let Some(rw) = end_time {
            query_params.insert("endTime".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetRateHistoryResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/history/rateHistory",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_simple_earn_flexible_product_list(
        &self,
        params: GetSimpleEarnFlexibleProductListParams,
    ) -> anyhow::Result<RestApiResponse<models::GetSimpleEarnFlexibleProductListResponse>> {
        let GetSimpleEarnFlexibleProductListParams {
            asset,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetSimpleEarnFlexibleProductListResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/list",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_simple_earn_locked_product_list(
        &self,
        params: GetSimpleEarnLockedProductListParams,
    ) -> anyhow::Result<RestApiResponse<models::GetSimpleEarnLockedProductListResponse>> {
        let GetSimpleEarnLockedProductListParams {
            asset,
            current,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = current {
            query_params.insert("current".to_string(), json!(rw));
        }

        if let Some(rw) = size {
            query_params.insert("size".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetSimpleEarnLockedProductListResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/list",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn redeem_flexible_product(
        &self,
        params: RedeemFlexibleProductParams,
    ) -> anyhow::Result<RestApiResponse<models::RedeemFlexibleProductResponse>> {
        let RedeemFlexibleProductParams {
            product_id,
            redeem_all,
            amount,
            dest_account,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("productId".to_string(), json!(product_id));

        if let Some(rw) = redeem_all {
            query_params.insert("redeemAll".to_string(), json!(rw));
        }

        if let Some(rw) = amount {
            query_params.insert("amount".to_string(), json!(rw));
        }

        if let Some(rw) = dest_account {
            query_params.insert("destAccount".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::RedeemFlexibleProductResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/redeem",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn redeem_locked_product(
        &self,
        params: RedeemLockedProductParams,
    ) -> anyhow::Result<RestApiResponse<models::RedeemLockedProductResponse>> {
        let RedeemLockedProductParams {
            position_id,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("positionId".to_string(), json!(position_id));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::RedeemLockedProductResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/redeem",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn set_flexible_auto_subscribe(
        &self,
        params: SetFlexibleAutoSubscribeParams,
    ) -> anyhow::Result<RestApiResponse<models::SetFlexibleAutoSubscribeResponse>> {
        let SetFlexibleAutoSubscribeParams {
            product_id,
            auto_subscribe,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("productId".to_string(), json!(product_id));

        query_params.insert("autoSubscribe".to_string(), json!(auto_subscribe));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::SetFlexibleAutoSubscribeResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/setAutoSubscribe",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn set_locked_auto_subscribe(
        &self,
        params: SetLockedAutoSubscribeParams,
    ) -> anyhow::Result<RestApiResponse<models::SetLockedAutoSubscribeResponse>> {
        let SetLockedAutoSubscribeParams {
            position_id,
            auto_subscribe,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("positionId".to_string(), json!(position_id));

        query_params.insert("autoSubscribe".to_string(), json!(auto_subscribe));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::SetLockedAutoSubscribeResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/setAutoSubscribe",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn set_locked_product_redeem_option(
        &self,
        params: SetLockedProductRedeemOptionParams,
    ) -> anyhow::Result<RestApiResponse<models::SetLockedProductRedeemOptionResponse>> {
        let SetLockedProductRedeemOptionParams {
            position_id,
            redeem_to,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("positionId".to_string(), json!(position_id));

        query_params.insert("redeemTo".to_string(), json!(redeem_to));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::SetLockedProductRedeemOptionResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/setRedeemOption",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn simple_account(
        &self,
        params: SimpleAccountParams,
    ) -> anyhow::Result<RestApiResponse<models::SimpleAccountResponse>> {
        let SimpleAccountParams { recv_window } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::SimpleAccountResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/account",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn subscribe_flexible_product(
        &self,
        params: SubscribeFlexibleProductParams,
    ) -> anyhow::Result<RestApiResponse<models::SubscribeFlexibleProductResponse>> {
        let SubscribeFlexibleProductParams {
            product_id,
            amount,
            auto_subscribe,
            source_account,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("productId".to_string(), json!(product_id));

        query_params.insert("amount".to_string(), json!(amount));

        if let Some(rw) = auto_subscribe {
            query_params.insert("autoSubscribe".to_string(), json!(rw));
        }

        if let Some(rw) = source_account {
            query_params.insert("sourceAccount".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::SubscribeFlexibleProductResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/flexible/subscribe",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn subscribe_locked_product(
        &self,
        params: SubscribeLockedProductParams,
    ) -> anyhow::Result<RestApiResponse<models::SubscribeLockedProductResponse>> {
        let SubscribeLockedProductParams {
            project_id,
            amount,
            auto_subscribe,
            source_account,
            redeem_to,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("projectId".to_string(), json!(project_id));

        query_params.insert("amount".to_string(), json!(amount));

        if let Some(rw) = auto_subscribe {
            query_params.insert("autoSubscribe".to_string(), json!(rw));
        }

        if let Some(rw) = source_account {
            query_params.insert("sourceAccount".to_string(), json!(rw));
        }

        if let Some(rw) = redeem_to {
            query_params.insert("redeemTo".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::SubscribeLockedProductResponse>(
            &self.configuration,
            "/sapi/v1/simple-earn/locked/subscribe",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }
}

#[cfg(all(test, feature = "simple_earn"))]
mod tests {
    use super::*;
    use crate::TOKIO_SHARED_RT;
    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
    use async_trait::async_trait;
    use std::collections::HashMap;

    struct DummyRestApiResponse<T> {
        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
        status: u16,
        headers: HashMap<String, String>,
        rate_limits: Option<Vec<RestApiRateLimit>>,
    }

    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
        fn from(dummy: DummyRestApiResponse<T>) -> Self {
            Self {
                data_fn: dummy.inner,
                status: dummy.status,
                headers: dummy.headers,
                rate_limits: dummy.rate_limits,
            }
        }
    }

    struct MockFlexibleLockedApiClient {
        force_error: bool,
    }

    #[async_trait]
    impl FlexibleLockedApi for MockFlexibleLockedApiClient {
        async fn get_collateral_record(
            &self,
            _params: GetCollateralRecordParams,
        ) -> anyhow::Result<RestApiResponse<models::GetCollateralRecordResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"100.00000000","productId":"BUSD001","asset":"USDT","createTime":1575018510000,"type":"REPAY","productName":"USDT","orderId":26055}],"total":"1"}"#).unwrap();
            let dummy_response: models::GetCollateralRecordResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetCollateralRecordResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_flexible_personal_left_quota(
            &self,
            _params: GetFlexiblePersonalLeftQuotaParams,
        ) -> anyhow::Result<RestApiResponse<models::GetFlexiblePersonalLeftQuotaResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"leftPersonalQuota":"1000"}"#).unwrap();
            let dummy_response: models::GetFlexiblePersonalLeftQuotaResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexiblePersonalLeftQuotaResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_flexible_product_position(
            &self,
            _params: GetFlexibleProductPositionParams,
        ) -> anyhow::Result<RestApiResponse<models::GetFlexibleProductPositionResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"totalAmount":"75.46000000","tierAnnualPercentageRate":{"0-5BTC":0.05,"5-10BTC":0.03},"latestAnnualPercentageRate":"0.02599895","yesterdayAirdropPercentageRate":"0.02599895","asset":"USDT","airDropAsset":"BETH","canRedeem":true,"collateralAmount":"232.23123213","productId":"USDT001","yesterdayRealTimeRewards":"0.10293829","cumulativeBonusRewards":"0.22759183","cumulativeRealTimeRewards":"0.22759183","cumulativeTotalRewards":"0.45459183","autoSubscribe":true}],"total":1}"#).unwrap();
            let dummy_response: models::GetFlexibleProductPositionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexibleProductPositionResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_flexible_redemption_record(
            &self,
            _params: GetFlexibleRedemptionRecordParams,
        ) -> anyhow::Result<RestApiResponse<models::GetFlexibleRedemptionRecordResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"10.54000000","asset":"USDT","time":1577257222000,"projectId":"USDT001","redeemId":40607,"destAccount":"SPOT","status":"PAID"}],"total":1}"#).unwrap();
            let dummy_response: models::GetFlexibleRedemptionRecordResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexibleRedemptionRecordResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_flexible_rewards_history(
            &self,
            _params: GetFlexibleRewardsHistoryParams,
        ) -> anyhow::Result<RestApiResponse<models::GetFlexibleRewardsHistoryResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"asset":"BUSD","rewards":"0.00006408","projectId":"USDT001","type":"BONUS","time":1577233578000},{"asset":"USDT","rewards":"0.00687654","projectId":"USDT001","type":"REALTIME","time":1577233562000}],"total":2}"#).unwrap();
            let dummy_response: models::GetFlexibleRewardsHistoryResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexibleRewardsHistoryResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_flexible_subscription_preview(
            &self,
            _params: GetFlexibleSubscriptionPreviewParams,
        ) -> anyhow::Result<RestApiResponse<models::GetFlexibleSubscriptionPreviewResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"totalAmount":"1232.32230982","rewardAsset":"BUSD","airDropAsset":"BETH","estDailyBonusRewards":"0.22759183","estDailyRealTimeRewards":"0.22759183","estDailyAirdropRewards":"0.22759183"}"#).unwrap();
            let dummy_response: models::GetFlexibleSubscriptionPreviewResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexibleSubscriptionPreviewResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_flexible_subscription_record(
            &self,
            _params: GetFlexibleSubscriptionRecordParams,
        ) -> anyhow::Result<RestApiResponse<models::GetFlexibleSubscriptionRecordResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"100.00000000","asset":"USDT","time":1575018510000,"purchaseId":26055,"productId":"USDT001","type":"AUTO","sourceAccount":"SPOT","amtFromSpot":"30","amtFromFunding":"70","status":"SUCCESS"}],"total":1}"#).unwrap();
            let dummy_response: models::GetFlexibleSubscriptionRecordResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexibleSubscriptionRecordResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_locked_personal_left_quota(
            &self,
            _params: GetLockedPersonalLeftQuotaParams,
        ) -> anyhow::Result<RestApiResponse<models::GetLockedPersonalLeftQuotaResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"leftPersonalQuota":"1000"}"#).unwrap();
            let dummy_response: models::GetLockedPersonalLeftQuotaResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetLockedPersonalLeftQuotaResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_locked_product_position(
            &self,
            _params: GetLockedProductPositionParams,
        ) -> anyhow::Result<RestApiResponse<models::GetLockedProductPositionResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"parentPositionId":123122,"projectId":"Axs*90","asset":"AXS","amount":"122.09202928","purchaseTime":"1646182276000","duration":"60","accrualDays":"4","rewardAsset":"AXS","APY":"0.2032","rewardAmt":"5.17181528","extraRewardAsset":"BNB","extraRewardAPR":"0.0203","estExtraRewardAmt":"5.17181528","boostRewardAsset":"AXS","boostApr":"0.0121","totalBoostRewardAmt":"3.98201829","nextPay":"1.29295383","nextPayDate":"1646697600000","payPeriod":"1","redeemAmountEarly":"2802.24068892","rewardsEndDate":"1651449600000","deliverDate":"1651536000000","redeemPeriod":"1","redeemingAmt":"232.2323","redeemTo":"FLEXIBLE","partialAmtDeliverDate":"1651536000000","canRedeemEarly":true,"canFastRedemption":true,"autoSubscribe":true,"type":"AUTO","status":"HOLDING","canReStake":true}],"total":1}"#).unwrap();
            let dummy_response: models::GetLockedProductPositionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetLockedProductPositionResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_locked_redemption_record(
            &self,
            _params: GetLockedRedemptionRecordParams,
        ) -> anyhow::Result<RestApiResponse<models::GetLockedRedemptionRecordResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"redeemId":40607,"time":1575018510000,"asset":"BNB","lockPeriod":"30","amount":"21312.23223","originalAmount":"21312.23223","type":"MATURE","deliverDate":"1575018510000","lossAmount":"0.00001232","isComplete":true,"rewardAsset":"AXS","rewardAmt":"5.17181528","extraRewardAsset":"BNB","estExtraRewardAmt":"5.17181528","status":"PAID"}],"total":1}"#).unwrap();
            let dummy_response: models::GetLockedRedemptionRecordResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetLockedRedemptionRecordResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_locked_rewards_history(
            &self,
            _params: GetLockedRewardsHistoryParams,
        ) -> anyhow::Result<RestApiResponse<models::GetLockedRewardsHistoryResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"time":1575018510000,"asset":"BNB","lockPeriod":"30","amount":"21312.23223","type":"Locked Rewards"},{"positionId":123123,"time":1575018510000,"asset":"BNB","amount":"1.23223","type":"Boost Rewards"}],"total":1}"#).unwrap();
            let dummy_response: models::GetLockedRewardsHistoryResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetLockedRewardsHistoryResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_locked_subscription_preview(
            &self,
            _params: GetLockedSubscriptionPreviewParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::GetLockedSubscriptionPreviewResponseInner>>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"[{"rewardAsset":"AXS","totalRewardAmt":"5.17181528","extraRewardAsset":"BNB","estTotalExtraRewardAmt":"5.17181528","boostRewardAsset":"AXS","estDailyRewardAmt":"1.20928901","nextPay":"1.29295383","nextPayDate":"1646697600000","valueDate":"1646697600000","rewardsEndDate":"1651449600000","deliverDate":"1651536000000","nextSubscriptionDate":"1651536000000"}]"#).unwrap();
            let dummy_response: Vec<models::GetLockedSubscriptionPreviewResponseInner> =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into Vec<models::GetLockedSubscriptionPreviewResponseInner>",
                );

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_locked_subscription_record(
            &self,
            _params: GetLockedSubscriptionRecordParams,
        ) -> anyhow::Result<RestApiResponse<models::GetLockedSubscriptionRecordResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"purchaseId":"26055","projectId":"Axs*90","time":1575018510000,"asset":"BNB","amount":"21312.23223","lockPeriod":"30","type":"AUTO","sourceAccount":"SPOT","amtFromSpot":"30","amtFromFunding":"70","status":"SUCCESS"}],"total":1}"#).unwrap();
            let dummy_response: models::GetLockedSubscriptionRecordResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetLockedSubscriptionRecordResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_rate_history(
            &self,
            _params: GetRateHistoryParams,
        ) -> anyhow::Result<RestApiResponse<models::GetRateHistoryResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"productId":"BUSD001","asset":"BUSD","annualPercentageRate":"0.00006408","time":1577233578000}],"total":"1"}"#).unwrap();
            let dummy_response: models::GetRateHistoryResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetRateHistoryResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_simple_earn_flexible_product_list(
            &self,
            _params: GetSimpleEarnFlexibleProductListParams,
        ) -> anyhow::Result<RestApiResponse<models::GetSimpleEarnFlexibleProductListResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"asset":"BTC","latestAnnualPercentageRate":"0.05000000","tierAnnualPercentageRate":{"0-5BTC":0.05,"5-10BTC":0.03},"airDropPercentageRate":"0.05000000","canPurchase":true,"canRedeem":true,"isSoldOut":true,"hot":true,"minPurchaseAmount":"0.01000000","productId":"BTC001","subscriptionStartTime":1646182276000,"status":"PURCHASING"}],"total":1}"#).unwrap();
            let dummy_response: models::GetSimpleEarnFlexibleProductListResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetSimpleEarnFlexibleProductListResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn get_simple_earn_locked_product_list(
            &self,
            _params: GetSimpleEarnLockedProductListParams,
        ) -> anyhow::Result<RestApiResponse<models::GetSimpleEarnLockedProductListResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"projectId":"Axs*90","detail":{"asset":"AXS","rewardAsset":"AXS","duration":90,"renewable":true,"isSoldOut":true,"apr":"1.2069","status":"CREATED","subscriptionStartTime":1646182276000,"extraRewardAsset":"BNB","extraRewardAPR":"0.23","boostRewardAsset":"AXS","boostApr":"0.0121","boostEndTime":1646182276000},"quota":{"totalPersonalQuota":"2","minimum":"0.001"}}],"total":1}"#).unwrap();
            let dummy_response: models::GetSimpleEarnLockedProductListResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetSimpleEarnLockedProductListResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn redeem_flexible_product(
            &self,
            _params: RedeemFlexibleProductParams,
        ) -> anyhow::Result<RestApiResponse<models::RedeemFlexibleProductResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value =
                serde_json::from_str(r#"{"redeemId":40607,"success":true}"#).unwrap();
            let dummy_response: models::RedeemFlexibleProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RedeemFlexibleProductResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn redeem_locked_product(
            &self,
            _params: RedeemLockedProductParams,
        ) -> anyhow::Result<RestApiResponse<models::RedeemLockedProductResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value =
                serde_json::from_str(r#"{"redeemId":40607,"success":true}"#).unwrap();
            let dummy_response: models::RedeemLockedProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RedeemLockedProductResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn set_flexible_auto_subscribe(
            &self,
            _params: SetFlexibleAutoSubscribeParams,
        ) -> anyhow::Result<RestApiResponse<models::SetFlexibleAutoSubscribeResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let dummy_response: models::SetFlexibleAutoSubscribeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetFlexibleAutoSubscribeResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn set_locked_auto_subscribe(
            &self,
            _params: SetLockedAutoSubscribeParams,
        ) -> anyhow::Result<RestApiResponse<models::SetLockedAutoSubscribeResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let dummy_response: models::SetLockedAutoSubscribeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetLockedAutoSubscribeResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn set_locked_product_redeem_option(
            &self,
            _params: SetLockedProductRedeemOptionParams,
        ) -> anyhow::Result<RestApiResponse<models::SetLockedProductRedeemOptionResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let dummy_response: models::SetLockedProductRedeemOptionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetLockedProductRedeemOptionResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn simple_account(
            &self,
            _params: SimpleAccountParams,
        ) -> anyhow::Result<RestApiResponse<models::SimpleAccountResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"totalAmountInBTC":"0.01067982","totalAmountInUSDT":"77.13289230","totalFlexibleAmountInBTC":"0.00000000","totalFlexibleAmountInUSDT":"0.00000000","totalLockedInBTC":"0.01067982","totalLockedInUSDT":"77.13289230"}"#).unwrap();
            let dummy_response: models::SimpleAccountResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SimpleAccountResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn subscribe_flexible_product(
            &self,
            _params: SubscribeFlexibleProductParams,
        ) -> anyhow::Result<RestApiResponse<models::SubscribeFlexibleProductResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value =
                serde_json::from_str(r#"{"purchaseId":40607,"success":true}"#).unwrap();
            let dummy_response: models::SubscribeFlexibleProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SubscribeFlexibleProductResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }

        async fn subscribe_locked_product(
            &self,
            _params: SubscribeLockedProductParams,
        ) -> anyhow::Result<RestApiResponse<models::SubscribeLockedProductResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value =
                serde_json::from_str(r#"{"purchaseId":40607,"positionId":"12345","success":true}"#)
                    .unwrap();
            let dummy_response: models::SubscribeLockedProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SubscribeLockedProductResponse");

            let dummy = DummyRestApiResponse {
                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
                status: 200,
                headers: HashMap::new(),
                rate_limits: None,
            };

            Ok(dummy.into())
        }
    }

    #[test]
    fn get_collateral_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetCollateralRecordParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"100.00000000","productId":"BUSD001","asset":"USDT","createTime":1575018510000,"type":"REPAY","productName":"USDT","orderId":26055}],"total":"1"}"#).unwrap();
            let expected_response : models::GetCollateralRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCollateralRecordResponse");

            let resp = client.get_collateral_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_collateral_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetCollateralRecordParams::builder().product_id("1".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"100.00000000","productId":"BUSD001","asset":"USDT","createTime":1575018510000,"type":"REPAY","productName":"USDT","orderId":26055}],"total":"1"}"#).unwrap();
            let expected_response : models::GetCollateralRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCollateralRecordResponse");

            let resp = client.get_collateral_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_collateral_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetCollateralRecordParams::builder().build().unwrap();

            match client.get_collateral_record(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_flexible_personal_left_quota_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexiblePersonalLeftQuotaParams::builder("1".to_string())
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"leftPersonalQuota":"1000"}"#).unwrap();
            let expected_response: models::GetFlexiblePersonalLeftQuotaResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexiblePersonalLeftQuotaResponse");

            let resp = client
                .get_flexible_personal_left_quota(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_personal_left_quota_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexiblePersonalLeftQuotaParams::builder("1".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"leftPersonalQuota":"1000"}"#).unwrap();
            let expected_response: models::GetFlexiblePersonalLeftQuotaResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetFlexiblePersonalLeftQuotaResponse");

            let resp = client
                .get_flexible_personal_left_quota(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_personal_left_quota_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetFlexiblePersonalLeftQuotaParams::builder("1".to_string())
                .build()
                .unwrap();

            match client.get_flexible_personal_left_quota(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_flexible_product_position_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleProductPositionParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"totalAmount":"75.46000000","tierAnnualPercentageRate":{"0-5BTC":0.05,"5-10BTC":0.03},"latestAnnualPercentageRate":"0.02599895","yesterdayAirdropPercentageRate":"0.02599895","asset":"USDT","airDropAsset":"BETH","canRedeem":true,"collateralAmount":"232.23123213","productId":"USDT001","yesterdayRealTimeRewards":"0.10293829","cumulativeBonusRewards":"0.22759183","cumulativeRealTimeRewards":"0.22759183","cumulativeTotalRewards":"0.45459183","autoSubscribe":true}],"total":1}"#).unwrap();
            let expected_response : models::GetFlexibleProductPositionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleProductPositionResponse");

            let resp = client.get_flexible_product_position(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_product_position_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleProductPositionParams::builder().asset("asset_example".to_string()).product_id("1".to_string()).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"totalAmount":"75.46000000","tierAnnualPercentageRate":{"0-5BTC":0.05,"5-10BTC":0.03},"latestAnnualPercentageRate":"0.02599895","yesterdayAirdropPercentageRate":"0.02599895","asset":"USDT","airDropAsset":"BETH","canRedeem":true,"collateralAmount":"232.23123213","productId":"USDT001","yesterdayRealTimeRewards":"0.10293829","cumulativeBonusRewards":"0.22759183","cumulativeRealTimeRewards":"0.22759183","cumulativeTotalRewards":"0.45459183","autoSubscribe":true}],"total":1}"#).unwrap();
            let expected_response : models::GetFlexibleProductPositionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleProductPositionResponse");

            let resp = client.get_flexible_product_position(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_product_position_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetFlexibleProductPositionParams::builder().build().unwrap();

            match client.get_flexible_product_position(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_flexible_redemption_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleRedemptionRecordParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"10.54000000","asset":"USDT","time":1577257222000,"projectId":"USDT001","redeemId":40607,"destAccount":"SPOT","status":"PAID"}],"total":1}"#).unwrap();
            let expected_response : models::GetFlexibleRedemptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleRedemptionRecordResponse");

            let resp = client.get_flexible_redemption_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_redemption_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleRedemptionRecordParams::builder().product_id("1".to_string()).redeem_id("1".to_string()).asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"10.54000000","asset":"USDT","time":1577257222000,"projectId":"USDT001","redeemId":40607,"destAccount":"SPOT","status":"PAID"}],"total":1}"#).unwrap();
            let expected_response : models::GetFlexibleRedemptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleRedemptionRecordResponse");

            let resp = client.get_flexible_redemption_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_redemption_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetFlexibleRedemptionRecordParams::builder()
                .build()
                .unwrap();

            match client.get_flexible_redemption_record(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_flexible_rewards_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleRewardsHistoryParams::builder("s".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"asset":"BUSD","rewards":"0.00006408","projectId":"USDT001","type":"BONUS","time":1577233578000},{"asset":"USDT","rewards":"0.00687654","projectId":"USDT001","type":"REALTIME","time":1577233562000}],"total":2}"#).unwrap();
            let expected_response : models::GetFlexibleRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleRewardsHistoryResponse");

            let resp = client.get_flexible_rewards_history(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_rewards_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleRewardsHistoryParams::builder("s".to_string(),).product_id("1".to_string()).asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"asset":"BUSD","rewards":"0.00006408","projectId":"USDT001","type":"BONUS","time":1577233578000},{"asset":"USDT","rewards":"0.00687654","projectId":"USDT001","type":"REALTIME","time":1577233562000}],"total":2}"#).unwrap();
            let expected_response : models::GetFlexibleRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleRewardsHistoryResponse");

            let resp = client.get_flexible_rewards_history(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_rewards_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetFlexibleRewardsHistoryParams::builder("s".to_string())
                .build()
                .unwrap();

            match client.get_flexible_rewards_history(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_flexible_subscription_preview_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleSubscriptionPreviewParams::builder("1".to_string(),dec!(1.0),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"totalAmount":"1232.32230982","rewardAsset":"BUSD","airDropAsset":"BETH","estDailyBonusRewards":"0.22759183","estDailyRealTimeRewards":"0.22759183","estDailyAirdropRewards":"0.22759183"}"#).unwrap();
            let expected_response : models::GetFlexibleSubscriptionPreviewResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleSubscriptionPreviewResponse");

            let resp = client.get_flexible_subscription_preview(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_subscription_preview_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleSubscriptionPreviewParams::builder("1".to_string(),dec!(1.0),).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"totalAmount":"1232.32230982","rewardAsset":"BUSD","airDropAsset":"BETH","estDailyBonusRewards":"0.22759183","estDailyRealTimeRewards":"0.22759183","estDailyAirdropRewards":"0.22759183"}"#).unwrap();
            let expected_response : models::GetFlexibleSubscriptionPreviewResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleSubscriptionPreviewResponse");

            let resp = client.get_flexible_subscription_preview(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_subscription_preview_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetFlexibleSubscriptionPreviewParams::builder("1".to_string(), dec!(1.0))
                .build()
                .unwrap();

            match client.get_flexible_subscription_preview(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_flexible_subscription_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleSubscriptionRecordParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"100.00000000","asset":"USDT","time":1575018510000,"purchaseId":26055,"productId":"USDT001","type":"AUTO","sourceAccount":"SPOT","amtFromSpot":"30","amtFromFunding":"70","status":"SUCCESS"}],"total":1}"#).unwrap();
            let expected_response : models::GetFlexibleSubscriptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleSubscriptionRecordResponse");

            let resp = client.get_flexible_subscription_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_subscription_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetFlexibleSubscriptionRecordParams::builder().product_id("1".to_string()).purchase_id("1".to_string()).asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"100.00000000","asset":"USDT","time":1575018510000,"purchaseId":26055,"productId":"USDT001","type":"AUTO","sourceAccount":"SPOT","amtFromSpot":"30","amtFromFunding":"70","status":"SUCCESS"}],"total":1}"#).unwrap();
            let expected_response : models::GetFlexibleSubscriptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFlexibleSubscriptionRecordResponse");

            let resp = client.get_flexible_subscription_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_flexible_subscription_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetFlexibleSubscriptionRecordParams::builder()
                .build()
                .unwrap();

            match client.get_flexible_subscription_record(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_locked_personal_left_quota_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedPersonalLeftQuotaParams::builder("1".to_string())
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"leftPersonalQuota":"1000"}"#).unwrap();
            let expected_response: models::GetLockedPersonalLeftQuotaResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetLockedPersonalLeftQuotaResponse");

            let resp = client
                .get_locked_personal_left_quota(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_personal_left_quota_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedPersonalLeftQuotaParams::builder("1".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"leftPersonalQuota":"1000"}"#).unwrap();
            let expected_response: models::GetLockedPersonalLeftQuotaResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetLockedPersonalLeftQuotaResponse");

            let resp = client
                .get_locked_personal_left_quota(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_personal_left_quota_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetLockedPersonalLeftQuotaParams::builder("1".to_string())
                .build()
                .unwrap();

            match client.get_locked_personal_left_quota(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_locked_product_position_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedProductPositionParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"parentPositionId":123122,"projectId":"Axs*90","asset":"AXS","amount":"122.09202928","purchaseTime":"1646182276000","duration":"60","accrualDays":"4","rewardAsset":"AXS","APY":"0.2032","rewardAmt":"5.17181528","extraRewardAsset":"BNB","extraRewardAPR":"0.0203","estExtraRewardAmt":"5.17181528","boostRewardAsset":"AXS","boostApr":"0.0121","totalBoostRewardAmt":"3.98201829","nextPay":"1.29295383","nextPayDate":"1646697600000","payPeriod":"1","redeemAmountEarly":"2802.24068892","rewardsEndDate":"1651449600000","deliverDate":"1651536000000","redeemPeriod":"1","redeemingAmt":"232.2323","redeemTo":"FLEXIBLE","partialAmtDeliverDate":"1651536000000","canRedeemEarly":true,"canFastRedemption":true,"autoSubscribe":true,"type":"AUTO","status":"HOLDING","canReStake":true}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedProductPositionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedProductPositionResponse");

            let resp = client.get_locked_product_position(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_product_position_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedProductPositionParams::builder().asset("asset_example".to_string()).position_id(1).project_id("1".to_string()).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"parentPositionId":123122,"projectId":"Axs*90","asset":"AXS","amount":"122.09202928","purchaseTime":"1646182276000","duration":"60","accrualDays":"4","rewardAsset":"AXS","APY":"0.2032","rewardAmt":"5.17181528","extraRewardAsset":"BNB","extraRewardAPR":"0.0203","estExtraRewardAmt":"5.17181528","boostRewardAsset":"AXS","boostApr":"0.0121","totalBoostRewardAmt":"3.98201829","nextPay":"1.29295383","nextPayDate":"1646697600000","payPeriod":"1","redeemAmountEarly":"2802.24068892","rewardsEndDate":"1651449600000","deliverDate":"1651536000000","redeemPeriod":"1","redeemingAmt":"232.2323","redeemTo":"FLEXIBLE","partialAmtDeliverDate":"1651536000000","canRedeemEarly":true,"canFastRedemption":true,"autoSubscribe":true,"type":"AUTO","status":"HOLDING","canReStake":true}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedProductPositionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedProductPositionResponse");

            let resp = client.get_locked_product_position(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_product_position_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetLockedProductPositionParams::builder().build().unwrap();

            match client.get_locked_product_position(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_locked_redemption_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedRedemptionRecordParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"redeemId":40607,"time":1575018510000,"asset":"BNB","lockPeriod":"30","amount":"21312.23223","originalAmount":"21312.23223","type":"MATURE","deliverDate":"1575018510000","lossAmount":"0.00001232","isComplete":true,"rewardAsset":"AXS","rewardAmt":"5.17181528","extraRewardAsset":"BNB","estExtraRewardAmt":"5.17181528","status":"PAID"}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedRedemptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedRedemptionRecordResponse");

            let resp = client.get_locked_redemption_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_redemption_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedRedemptionRecordParams::builder().position_id(1).redeem_id("1".to_string()).asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"redeemId":40607,"time":1575018510000,"asset":"BNB","lockPeriod":"30","amount":"21312.23223","originalAmount":"21312.23223","type":"MATURE","deliverDate":"1575018510000","lossAmount":"0.00001232","isComplete":true,"rewardAsset":"AXS","rewardAmt":"5.17181528","extraRewardAsset":"BNB","estExtraRewardAmt":"5.17181528","status":"PAID"}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedRedemptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedRedemptionRecordResponse");

            let resp = client.get_locked_redemption_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_redemption_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetLockedRedemptionRecordParams::builder().build().unwrap();

            match client.get_locked_redemption_record(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_locked_rewards_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedRewardsHistoryParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"time":1575018510000,"asset":"BNB","lockPeriod":"30","amount":"21312.23223","type":"Locked Rewards"},{"positionId":123123,"time":1575018510000,"asset":"BNB","amount":"1.23223","type":"Boost Rewards"}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedRewardsHistoryResponse");

            let resp = client.get_locked_rewards_history(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_rewards_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedRewardsHistoryParams::builder().position_id(1).asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"time":1575018510000,"asset":"BNB","lockPeriod":"30","amount":"21312.23223","type":"Locked Rewards"},{"positionId":123123,"time":1575018510000,"asset":"BNB","amount":"1.23223","type":"Boost Rewards"}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedRewardsHistoryResponse");

            let resp = client.get_locked_rewards_history(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_rewards_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetLockedRewardsHistoryParams::builder().build().unwrap();

            match client.get_locked_rewards_history(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_locked_subscription_preview_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedSubscriptionPreviewParams::builder("1".to_string(),dec!(1.0),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"rewardAsset":"AXS","totalRewardAmt":"5.17181528","extraRewardAsset":"BNB","estTotalExtraRewardAmt":"5.17181528","boostRewardAsset":"AXS","estDailyRewardAmt":"1.20928901","nextPay":"1.29295383","nextPayDate":"1646697600000","valueDate":"1646697600000","rewardsEndDate":"1651449600000","deliverDate":"1651536000000","nextSubscriptionDate":"1651536000000"}]"#).unwrap();
            let expected_response : Vec<models::GetLockedSubscriptionPreviewResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetLockedSubscriptionPreviewResponseInner>");

            let resp = client.get_locked_subscription_preview(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_subscription_preview_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedSubscriptionPreviewParams::builder("1".to_string(),dec!(1.0),).auto_subscribe(true).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"rewardAsset":"AXS","totalRewardAmt":"5.17181528","extraRewardAsset":"BNB","estTotalExtraRewardAmt":"5.17181528","boostRewardAsset":"AXS","estDailyRewardAmt":"1.20928901","nextPay":"1.29295383","nextPayDate":"1646697600000","valueDate":"1646697600000","rewardsEndDate":"1651449600000","deliverDate":"1651536000000","nextSubscriptionDate":"1651536000000"}]"#).unwrap();
            let expected_response : Vec<models::GetLockedSubscriptionPreviewResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetLockedSubscriptionPreviewResponseInner>");

            let resp = client.get_locked_subscription_preview(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_subscription_preview_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetLockedSubscriptionPreviewParams::builder("1".to_string(), dec!(1.0))
                .build()
                .unwrap();

            match client.get_locked_subscription_preview(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_locked_subscription_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedSubscriptionRecordParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"purchaseId":"26055","projectId":"Axs*90","time":1575018510000,"asset":"BNB","amount":"21312.23223","lockPeriod":"30","type":"AUTO","sourceAccount":"SPOT","amtFromSpot":"30","amtFromFunding":"70","status":"SUCCESS"}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedSubscriptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedSubscriptionRecordResponse");

            let resp = client.get_locked_subscription_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_subscription_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetLockedSubscriptionRecordParams::builder().purchase_id("1".to_string()).asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"positionId":123123,"purchaseId":"26055","projectId":"Axs*90","time":1575018510000,"asset":"BNB","amount":"21312.23223","lockPeriod":"30","type":"AUTO","sourceAccount":"SPOT","amtFromSpot":"30","amtFromFunding":"70","status":"SUCCESS"}],"total":1}"#).unwrap();
            let expected_response : models::GetLockedSubscriptionRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetLockedSubscriptionRecordResponse");

            let resp = client.get_locked_subscription_record(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_locked_subscription_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetLockedSubscriptionRecordParams::builder()
                .build()
                .unwrap();

            match client.get_locked_subscription_record(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_rate_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetRateHistoryParams::builder("1".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"productId":"BUSD001","asset":"BUSD","annualPercentageRate":"0.00006408","time":1577233578000}],"total":"1"}"#).unwrap();
            let expected_response : models::GetRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRateHistoryResponse");

            let resp = client.get_rate_history(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_rate_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetRateHistoryParams::builder("1".to_string(),).apr_period("DAY".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"productId":"BUSD001","asset":"BUSD","annualPercentageRate":"0.00006408","time":1577233578000}],"total":"1"}"#).unwrap();
            let expected_response : models::GetRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRateHistoryResponse");

            let resp = client.get_rate_history(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_rate_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetRateHistoryParams::builder("1".to_string())
                .build()
                .unwrap();

            match client.get_rate_history(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_simple_earn_flexible_product_list_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetSimpleEarnFlexibleProductListParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"asset":"BTC","latestAnnualPercentageRate":"0.05000000","tierAnnualPercentageRate":{"0-5BTC":0.05,"5-10BTC":0.03},"airDropPercentageRate":"0.05000000","canPurchase":true,"canRedeem":true,"isSoldOut":true,"hot":true,"minPurchaseAmount":"0.01000000","productId":"BTC001","subscriptionStartTime":1646182276000,"status":"PURCHASING"}],"total":1}"#).unwrap();
            let expected_response : models::GetSimpleEarnFlexibleProductListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSimpleEarnFlexibleProductListResponse");

            let resp = client.get_simple_earn_flexible_product_list(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_simple_earn_flexible_product_list_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetSimpleEarnFlexibleProductListParams::builder().asset("asset_example".to_string()).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"asset":"BTC","latestAnnualPercentageRate":"0.05000000","tierAnnualPercentageRate":{"0-5BTC":0.05,"5-10BTC":0.03},"airDropPercentageRate":"0.05000000","canPurchase":true,"canRedeem":true,"isSoldOut":true,"hot":true,"minPurchaseAmount":"0.01000000","productId":"BTC001","subscriptionStartTime":1646182276000,"status":"PURCHASING"}],"total":1}"#).unwrap();
            let expected_response : models::GetSimpleEarnFlexibleProductListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSimpleEarnFlexibleProductListResponse");

            let resp = client.get_simple_earn_flexible_product_list(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_simple_earn_flexible_product_list_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetSimpleEarnFlexibleProductListParams::builder()
                .build()
                .unwrap();

            match client.get_simple_earn_flexible_product_list(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_simple_earn_locked_product_list_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetSimpleEarnLockedProductListParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"projectId":"Axs*90","detail":{"asset":"AXS","rewardAsset":"AXS","duration":90,"renewable":true,"isSoldOut":true,"apr":"1.2069","status":"CREATED","subscriptionStartTime":1646182276000,"extraRewardAsset":"BNB","extraRewardAPR":"0.23","boostRewardAsset":"AXS","boostApr":"0.0121","boostEndTime":1646182276000},"quota":{"totalPersonalQuota":"2","minimum":"0.001"}}],"total":1}"#).unwrap();
            let expected_response : models::GetSimpleEarnLockedProductListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSimpleEarnLockedProductListResponse");

            let resp = client.get_simple_earn_locked_product_list(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_simple_earn_locked_product_list_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = GetSimpleEarnLockedProductListParams::builder().asset("asset_example".to_string()).current(1).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"projectId":"Axs*90","detail":{"asset":"AXS","rewardAsset":"AXS","duration":90,"renewable":true,"isSoldOut":true,"apr":"1.2069","status":"CREATED","subscriptionStartTime":1646182276000,"extraRewardAsset":"BNB","extraRewardAPR":"0.23","boostRewardAsset":"AXS","boostApr":"0.0121","boostEndTime":1646182276000},"quota":{"totalPersonalQuota":"2","minimum":"0.001"}}],"total":1}"#).unwrap();
            let expected_response : models::GetSimpleEarnLockedProductListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSimpleEarnLockedProductListResponse");

            let resp = client.get_simple_earn_locked_product_list(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn get_simple_earn_locked_product_list_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = GetSimpleEarnLockedProductListParams::builder()
                .build()
                .unwrap();

            match client.get_simple_earn_locked_product_list(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn redeem_flexible_product_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = RedeemFlexibleProductParams::builder("1".to_string())
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"redeemId":40607,"success":true}"#).unwrap();
            let expected_response: models::RedeemFlexibleProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RedeemFlexibleProductResponse");

            let resp = client
                .redeem_flexible_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn redeem_flexible_product_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = RedeemFlexibleProductParams::builder("1".to_string())
                .redeem_all(false)
                .amount(dec!(1.0))
                .dest_account("SPOT".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"redeemId":40607,"success":true}"#).unwrap();
            let expected_response: models::RedeemFlexibleProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RedeemFlexibleProductResponse");

            let resp = client
                .redeem_flexible_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn redeem_flexible_product_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = RedeemFlexibleProductParams::builder("1".to_string())
                .build()
                .unwrap();

            match client.redeem_flexible_product(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn redeem_locked_product_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = RedeemLockedProductParams::builder("1".to_string())
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"redeemId":40607,"success":true}"#).unwrap();
            let expected_response: models::RedeemLockedProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RedeemLockedProductResponse");

            let resp = client
                .redeem_locked_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn redeem_locked_product_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = RedeemLockedProductParams::builder("1".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"redeemId":40607,"success":true}"#).unwrap();
            let expected_response: models::RedeemLockedProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RedeemLockedProductResponse");

            let resp = client
                .redeem_locked_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn redeem_locked_product_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = RedeemLockedProductParams::builder("1".to_string())
                .build()
                .unwrap();

            match client.redeem_locked_product(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn set_flexible_auto_subscribe_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SetFlexibleAutoSubscribeParams::builder("1".to_string(), true)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let expected_response: models::SetFlexibleAutoSubscribeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetFlexibleAutoSubscribeResponse");

            let resp = client
                .set_flexible_auto_subscribe(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn set_flexible_auto_subscribe_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SetFlexibleAutoSubscribeParams::builder("1".to_string(), true)
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let expected_response: models::SetFlexibleAutoSubscribeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetFlexibleAutoSubscribeResponse");

            let resp = client
                .set_flexible_auto_subscribe(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn set_flexible_auto_subscribe_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = SetFlexibleAutoSubscribeParams::builder("1".to_string(), true)
                .build()
                .unwrap();

            match client.set_flexible_auto_subscribe(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn set_locked_auto_subscribe_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SetLockedAutoSubscribeParams::builder("1".to_string(), true)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let expected_response: models::SetLockedAutoSubscribeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetLockedAutoSubscribeResponse");

            let resp = client
                .set_locked_auto_subscribe(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn set_locked_auto_subscribe_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SetLockedAutoSubscribeParams::builder("1".to_string(), true)
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let expected_response: models::SetLockedAutoSubscribeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetLockedAutoSubscribeResponse");

            let resp = client
                .set_locked_auto_subscribe(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn set_locked_auto_subscribe_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = SetLockedAutoSubscribeParams::builder("1".to_string(), true)
                .build()
                .unwrap();

            match client.set_locked_auto_subscribe(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn set_locked_product_redeem_option_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SetLockedProductRedeemOptionParams::builder(
                "1".to_string(),
                "redeem_to_example".to_string(),
            )
            .build()
            .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let expected_response: models::SetLockedProductRedeemOptionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetLockedProductRedeemOptionResponse");

            let resp = client
                .set_locked_product_redeem_option(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn set_locked_product_redeem_option_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SetLockedProductRedeemOptionParams::builder(
                "1".to_string(),
                "redeem_to_example".to_string(),
            )
            .recv_window(5000)
            .build()
            .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
            let expected_response: models::SetLockedProductRedeemOptionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SetLockedProductRedeemOptionResponse");

            let resp = client
                .set_locked_product_redeem_option(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn set_locked_product_redeem_option_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = SetLockedProductRedeemOptionParams::builder(
                "1".to_string(),
                "redeem_to_example".to_string(),
            )
            .build()
            .unwrap();

            match client.set_locked_product_redeem_option(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn simple_account_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SimpleAccountParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"totalAmountInBTC":"0.01067982","totalAmountInUSDT":"77.13289230","totalFlexibleAmountInBTC":"0.00000000","totalFlexibleAmountInUSDT":"0.00000000","totalLockedInBTC":"0.01067982","totalLockedInUSDT":"77.13289230"}"#).unwrap();
            let expected_response : models::SimpleAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SimpleAccountResponse");

            let resp = client.simple_account(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn simple_account_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SimpleAccountParams::builder().recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"totalAmountInBTC":"0.01067982","totalAmountInUSDT":"77.13289230","totalFlexibleAmountInBTC":"0.00000000","totalFlexibleAmountInUSDT":"0.00000000","totalLockedInBTC":"0.01067982","totalLockedInUSDT":"77.13289230"}"#).unwrap();
            let expected_response : models::SimpleAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SimpleAccountResponse");

            let resp = client.simple_account(params).await.expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn simple_account_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = SimpleAccountParams::builder().build().unwrap();

            match client.simple_account(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn subscribe_flexible_product_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SubscribeFlexibleProductParams::builder("1".to_string(), dec!(1.0))
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"purchaseId":40607,"success":true}"#).unwrap();
            let expected_response: models::SubscribeFlexibleProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SubscribeFlexibleProductResponse");

            let resp = client
                .subscribe_flexible_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn subscribe_flexible_product_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SubscribeFlexibleProductParams::builder("1".to_string(), dec!(1.0))
                .auto_subscribe(true)
                .source_account("SPOT".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"purchaseId":40607,"success":true}"#).unwrap();
            let expected_response: models::SubscribeFlexibleProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SubscribeFlexibleProductResponse");

            let resp = client
                .subscribe_flexible_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn subscribe_flexible_product_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = SubscribeFlexibleProductParams::builder("1".to_string(), dec!(1.0))
                .build()
                .unwrap();

            match client.subscribe_flexible_product(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn subscribe_locked_product_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SubscribeLockedProductParams::builder("1".to_string(), dec!(1.0))
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"purchaseId":40607,"positionId":"12345","success":true}"#)
                    .unwrap();
            let expected_response: models::SubscribeLockedProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SubscribeLockedProductResponse");

            let resp = client
                .subscribe_locked_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn subscribe_locked_product_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: false };

            let params = SubscribeLockedProductParams::builder("1".to_string(), dec!(1.0))
                .auto_subscribe(true)
                .source_account("SPOT".to_string())
                .redeem_to("SPOT".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"purchaseId":40607,"positionId":"12345","success":true}"#)
                    .unwrap();
            let expected_response: models::SubscribeLockedProductResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::SubscribeLockedProductResponse");

            let resp = client
                .subscribe_locked_product(params)
                .await
                .expect("Expected a response");
            let data_future = resp.data();
            let actual_response = data_future.await.unwrap();
            assert_eq!(actual_response, expected_response);
        });
    }

    #[test]
    fn subscribe_locked_product_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockFlexibleLockedApiClient { force_error: true };

            let params = SubscribeLockedProductParams::builder("1".to_string(), dec!(1.0))
                .build()
                .unwrap();

            match client.subscribe_locked_product(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }
}
