use crate::{
models::{prelude::{AssetData, AssetType}, Order, Request},
BuildQueryParametersExt,
};
use stellar_rust_sdk_derive::pagination;
#[pagination]
#[derive(Default)]
pub struct AllLiquidityPoolsRequest {
reserves: Option<Vec<AssetType>>,
}
impl AllLiquidityPoolsRequest {
pub fn new() -> AllLiquidityPoolsRequest {
AllLiquidityPoolsRequest {
cursor: None,
limit: None,
order: None,
reserves: None,
}
}
pub fn add_native_reserve(mut self) -> AllLiquidityPoolsRequest {
match self.reserves {
Some(ref mut reserves) => reserves.push(AssetType::Native),
None => self.reserves = Some(vec![AssetType::Native]),
}
self
}
pub fn add_alphanumeric4_reserve(
mut self,
asset_code: impl Into<String>,
asset_issuer: impl Into<String>,
) -> AllLiquidityPoolsRequest {
let asset_code = asset_code.into();
let asset_issuer = asset_issuer.into();
match self.reserves {
Some(ref mut reserves) => reserves.push(AssetType::Alphanumeric4(AssetData {
asset_code,
asset_issuer,
})),
None => {
self.reserves = Some(vec![AssetType::Alphanumeric4(AssetData{
asset_code,
asset_issuer,
})])
}
}
self
}
pub fn add_alphanumeric12_reserve(
mut self,
asset_code: impl Into<String>,
asset_issuer: impl Into<String>,
) -> AllLiquidityPoolsRequest {
let asset_code = asset_code.into();
let asset_issuer = asset_issuer.into();
match self.reserves {
Some(ref mut reserves) => reserves.push(AssetType::Alphanumeric12(AssetData {
asset_code,
asset_issuer,
})),
None => {
self.reserves = Some(vec![AssetType::Alphanumeric12(AssetData {
asset_code,
asset_issuer,
})])
}
}
self
}
}
impl Request for AllLiquidityPoolsRequest {
fn get_query_parameters(&self) -> String {
let query_reserve_parameters = self
.reserves
.as_ref()
.map_or_else(Vec::new, |reserves| {
reserves
.iter()
.enumerate()
.fold(Vec::new(), |mut acc, (i, reserve)| {
let separator = if i == 0 { "reserves=" } else { "%2C" };
match reserve {
AssetType::Native => acc.push(format!("{}native", separator)),
AssetType::Alphanumeric4(reserve)
| AssetType::Alphanumeric12(reserve) => {
acc.push(format!(
"{}{}%3A{}",
separator, reserve.asset_code, reserve.asset_issuer
));
}
}
acc
})
})
.join("");
vec![
self.cursor.as_ref().map(|c| format!("cursor={}", c)),
self.limit.as_ref().map(|l| format!("limit={}", l)),
self.order.as_ref().map(|o| format!("order={}", o)),
Some(query_reserve_parameters),
]
.build_query_parameters()
}
fn build_url(&self, base_url: &str) -> String {
format!(
"{}/{}?{}",
base_url,
super::LIQUIDITY_POOLS_PATH,
self.get_query_parameters()
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let request = AllLiquidityPoolsRequest::new();
assert_eq!(request.cursor, None);
assert_eq!(request.limit, None);
assert_eq!(request.order, None);
assert_eq!(request.reserves, None);
}
#[test]
fn test_set_cursor() {
let request = AllLiquidityPoolsRequest::new().set_cursor(1234).unwrap();
assert_eq!(request.cursor, Some(1234));
}
#[test]
fn test_set_limit() {
let request = AllLiquidityPoolsRequest::new().set_limit(20).unwrap();
assert_eq!(request.limit, Some(20));
}
#[test]
fn test_set_order() {
let request = AllLiquidityPoolsRequest::new()
.set_order(Order::Desc)
.unwrap();
assert_eq!(request.order, Some(Order::Desc));
}
#[test]
fn test_add_native_reserve() {
let request = AllLiquidityPoolsRequest::new().add_native_reserve();
assert_eq!(request.reserves, Some(vec![AssetType::Native]));
}
#[test]
fn test_add_native_reserve_twice() {
let request = AllLiquidityPoolsRequest::new()
.add_native_reserve()
.add_native_reserve();
assert_eq!(
request.reserves,
Some(vec![AssetType::Native, AssetType::Native])
);
}
#[test]
fn test_add_alphanumeric4_reserve() {
let mut request = AllLiquidityPoolsRequest::new();
request = request.add_alphanumeric4_reserve("USD", "issuer");
if let Some(reserves) = request.reserves {
assert_eq!(reserves.len(), 1);
match &reserves[0] {
AssetType::Alphanumeric4(reserve) => {
assert_eq!(reserve.asset_code, "USD");
assert_eq!(reserve.asset_issuer, "issuer");
}
_ => panic!("AssetData type is not Alphanumeric4"),
}
} else {
panic!("Reserves is None");
}
}
#[test]
fn test_add_alphanumeric12_reserve() {
let mut request = AllLiquidityPoolsRequest::new();
request = request.add_alphanumeric12_reserve("LONGASSET", "issuer");
if let Some(reserves) = request.reserves {
assert_eq!(reserves.len(), 1);
match &reserves[0] {
AssetType::Alphanumeric12(reserve) => {
assert_eq!(reserve.asset_code, "LONGASSET");
assert_eq!(reserve.asset_issuer, "issuer");
}
_ => panic!("AssetData type is not Alphanumeric12"),
}
} else {
panic!("Reserves is None");
}
}
#[test]
fn test_get_query_parameters() {
let mut request = AllLiquidityPoolsRequest::new();
request = request.add_alphanumeric4_reserve("USD", "issuer");
let query_parameters = request.get_query_parameters();
assert_eq!(query_parameters, "?reserves=USD%3Aissuer");
}
}