use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::Coin;
#[cfg(feature = "cosmwasm_1_3")]
use crate::PageRequest;
use crate::{Binary, DenomMetadata};
use super::query_response::QueryResponseType;
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum BankQuery {
    #[cfg(feature = "cosmwasm_1_1")]
    Supply { denom: String },
    Balance { address: String, denom: String },
    AllBalances { address: String },
    #[cfg(feature = "cosmwasm_1_3")]
    DenomMetadata { denom: String },
    #[cfg(feature = "cosmwasm_1_3")]
    AllDenomMetadata { pagination: Option<PageRequest> },
}
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub struct SupplyResponse {
    pub amount: Coin,
}
impl_response_constructor!(SupplyResponse, amount: Coin);
impl QueryResponseType for SupplyResponse {}
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct BalanceResponse {
    pub amount: Coin,
}
impl_response_constructor!(BalanceResponse, amount: Coin);
impl QueryResponseType for BalanceResponse {}
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct AllBalanceResponse {
    pub amount: Vec<Coin>,
}
impl_response_constructor!(AllBalanceResponse, amount: Vec<Coin>);
impl QueryResponseType for AllBalanceResponse {}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub struct DenomMetadataResponse {
    pub metadata: DenomMetadata,
}
impl_response_constructor!(DenomMetadataResponse, metadata: DenomMetadata);
impl QueryResponseType for DenomMetadataResponse {}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub struct AllDenomMetadataResponse {
    pub metadata: Vec<DenomMetadata>,
    pub next_key: Option<Binary>,
}
impl_response_constructor!(
    AllDenomMetadataResponse,
    metadata: Vec<DenomMetadata>,
    next_key: Option<Binary>
);
impl QueryResponseType for AllDenomMetadataResponse {}
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn private_constructor_works() {
        let response = AllBalanceResponse::new(vec![Coin::new(1234, "uatom")]);
        assert_eq!(
            response,
            AllBalanceResponse {
                amount: vec![Coin::new(1234, "uatom")]
            }
        );
    }
}