use crate::client::QueryPairs;
pub(crate) trait ToQuery {
fn to_query(&self) -> QueryPairs;
}
fn push<T: ToString>(pairs: &mut QueryPairs, name: &'static str, value: &Option<T>) {
if let Some(value) = value {
pairs.push((name, value.to_string()));
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DiscoverTab {
Trending,
New,
Gainers,
Graduating,
}
impl DiscoverTab {
pub fn as_str(self) -> &'static str {
match self {
DiscoverTab::Trending => "trending",
DiscoverTab::New => "new",
DiscoverTab::Gainers => "gainers",
DiscoverTab::Graduating => "graduating",
}
}
}
impl std::fmt::Display for DiscoverTab {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenStatus {
Bonding,
Graduated,
}
impl TokenStatus {
pub fn as_str(self) -> &'static str {
match self {
TokenStatus::Bonding => "bonding",
TokenStatus::Graduated => "graduated",
}
}
}
impl std::fmt::Display for TokenStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SortDirection {
Asc,
Desc,
}
impl SortDirection {
pub fn as_str(self) -> &'static str {
match self {
SortDirection::Asc => "asc",
SortDirection::Desc => "desc",
}
}
}
impl std::fmt::Display for SortDirection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Default)]
pub struct DiscoverParams {
pub tab: Option<DiscoverTab>,
pub network: Option<String>,
pub min_marketcap: Option<f64>,
pub min_volume: Option<f64>,
pub min_holders: Option<i64>,
pub max_age_secs: Option<i64>,
pub status: Option<TokenStatus>,
pub limit: Option<i64>,
}
impl DiscoverParams {
pub fn new() -> Self {
Self::default()
}
pub fn tab(mut self, tab: DiscoverTab) -> Self {
self.tab = Some(tab);
self
}
pub fn network(mut self, network: impl Into<String>) -> Self {
self.network = Some(network.into());
self
}
pub fn min_marketcap(mut self, min_marketcap: f64) -> Self {
self.min_marketcap = Some(min_marketcap);
self
}
pub fn min_volume(mut self, min_volume: f64) -> Self {
self.min_volume = Some(min_volume);
self
}
pub fn min_holders(mut self, min_holders: i64) -> Self {
self.min_holders = Some(min_holders);
self
}
pub fn max_age_secs(mut self, max_age_secs: i64) -> Self {
self.max_age_secs = Some(max_age_secs);
self
}
pub fn status(mut self, status: TokenStatus) -> Self {
self.status = Some(status);
self
}
pub fn limit(mut self, limit: i64) -> Self {
self.limit = Some(limit);
self
}
}
impl ToQuery for DiscoverParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "tab", &self.tab.map(|t| t.as_str()));
push(&mut pairs, "network", &self.network);
push(&mut pairs, "minMarketcap", &self.min_marketcap);
push(&mut pairs, "minVolume", &self.min_volume);
push(&mut pairs, "minHolders", &self.min_holders);
push(&mut pairs, "maxAgeSecs", &self.max_age_secs);
push(&mut pairs, "status", &self.status.map(|s| s.as_str()));
push(&mut pairs, "limit", &self.limit);
pairs
}
}
#[derive(Debug, Clone, Default)]
pub struct ListTokensParams {
pub order_type: Option<String>,
pub order_flag: Option<SortDirection>,
pub search_word: Option<String>,
pub network: Option<String>,
pub style: Option<String>,
pub include_nsfw: Option<bool>,
pub page_number: Option<i64>,
pub page_size: Option<i64>,
}
impl ListTokensParams {
pub fn new() -> Self {
Self::default()
}
pub fn order_type(mut self, order_type: impl Into<String>) -> Self {
self.order_type = Some(order_type.into());
self
}
pub fn order_flag(mut self, order_flag: SortDirection) -> Self {
self.order_flag = Some(order_flag);
self
}
pub fn search_word(mut self, search_word: impl Into<String>) -> Self {
self.search_word = Some(search_word.into());
self
}
pub fn network(mut self, network: impl Into<String>) -> Self {
self.network = Some(network.into());
self
}
pub fn style(mut self, style: impl Into<String>) -> Self {
self.style = Some(style.into());
self
}
pub fn include_nsfw(mut self, include_nsfw: bool) -> Self {
self.include_nsfw = Some(include_nsfw);
self
}
pub fn page_number(mut self, page_number: i64) -> Self {
self.page_number = Some(page_number);
self
}
pub fn page_size(mut self, page_size: i64) -> Self {
self.page_size = Some(page_size);
self
}
}
impl ToQuery for ListTokensParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "orderType", &self.order_type);
push(
&mut pairs,
"orderFlag",
&self.order_flag.map(|f| f.as_str()),
);
push(&mut pairs, "searchWord", &self.search_word);
push(&mut pairs, "network", &self.network);
push(&mut pairs, "style", &self.style);
push(&mut pairs, "includeNsfw", &self.include_nsfw);
push(&mut pairs, "pageNumber", &self.page_number);
push(&mut pairs, "pageSize", &self.page_size);
pairs
}
}
#[derive(Debug, Clone, Default)]
pub struct TokenDetailParams {
pub page_number: Option<i64>,
pub page_size: Option<i64>,
}
impl TokenDetailParams {
pub fn new() -> Self {
Self::default()
}
pub fn page_number(mut self, page_number: i64) -> Self {
self.page_number = Some(page_number);
self
}
pub fn page_size(mut self, page_size: i64) -> Self {
self.page_size = Some(page_size);
self
}
}
impl ToQuery for TokenDetailParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "pageNumber", &self.page_number);
push(&mut pairs, "pageSize", &self.page_size);
pairs
}
}
#[derive(Debug, Clone, Default)]
pub struct RecentTradesParams {
pub latest_trade_id: Option<i64>,
pub latest_token_id: Option<i64>,
}
impl RecentTradesParams {
pub fn new() -> Self {
Self::default()
}
pub fn latest_trade_id(mut self, latest_trade_id: i64) -> Self {
self.latest_trade_id = Some(latest_trade_id);
self
}
pub fn latest_token_id(mut self, latest_token_id: i64) -> Self {
self.latest_token_id = Some(latest_token_id);
self
}
}
impl ToQuery for RecentTradesParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "latestTradeId", &self.latest_trade_id);
push(&mut pairs, "latestTokenId", &self.latest_token_id);
pairs
}
}
#[derive(Debug, Clone, Default)]
pub struct TokenTradesParams {
pub limit: Option<i64>,
pub offset: Option<i64>,
}
impl TokenTradesParams {
pub fn new() -> Self {
Self::default()
}
pub fn limit(mut self, limit: i64) -> Self {
self.limit = Some(limit);
self
}
pub fn offset(mut self, offset: i64) -> Self {
self.offset = Some(offset);
self
}
}
impl ToQuery for TokenTradesParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "limit", &self.limit);
push(&mut pairs, "offset", &self.offset);
pairs
}
}
#[derive(Debug, Clone)]
pub struct ChartDataParams {
pub token_address: String,
pub interval: String,
pub from: i64,
pub to: i64,
pub first: Option<i64>,
pub dex: Option<String>,
pub count_back: Option<i64>,
}
impl ChartDataParams {
pub fn new(
token_address: impl Into<String>,
interval: impl Into<String>,
from: i64,
to: i64,
) -> Self {
Self {
token_address: token_address.into(),
interval: interval.into(),
from,
to,
first: None,
dex: None,
count_back: None,
}
}
pub fn first(mut self, first: i64) -> Self {
self.first = Some(first);
self
}
pub fn dex(mut self, dex: impl Into<String>) -> Self {
self.dex = Some(dex.into());
self
}
pub fn count_back(mut self, count_back: i64) -> Self {
self.count_back = Some(count_back);
self
}
}
impl ToQuery for ChartDataParams {
fn to_query(&self) -> QueryPairs {
let mut pairs: QueryPairs = vec![
("tokenAddress", self.token_address.clone()),
("interval", self.interval.clone()),
("from", self.from.to_string()),
("to", self.to.to_string()),
];
push(&mut pairs, "first", &self.first);
push(&mut pairs, "dex", &self.dex);
push(&mut pairs, "countBack", &self.count_back);
pairs
}
}
#[derive(Debug, Clone, Default)]
pub struct TopHoldersParams {
pub from: Option<i64>,
pub to: Option<i64>,
pub network: Option<String>,
}
impl TopHoldersParams {
pub fn new() -> Self {
Self::default()
}
pub fn from(mut self, from: i64) -> Self {
self.from = Some(from);
self
}
pub fn to(mut self, to: i64) -> Self {
self.to = Some(to);
self
}
pub fn network(mut self, network: impl Into<String>) -> Self {
self.network = Some(network.into());
self
}
}
impl ToQuery for TopHoldersParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "from", &self.from);
push(&mut pairs, "to", &self.to);
push(&mut pairs, "network", &self.network);
pairs
}
}
#[derive(Debug, Clone, Default)]
pub struct SharesParams {
pub from: Option<i64>,
pub to: Option<i64>,
pub limit: Option<i64>,
}
impl SharesParams {
pub fn new() -> Self {
Self::default()
}
pub fn from(mut self, from: i64) -> Self {
self.from = Some(from);
self
}
pub fn to(mut self, to: i64) -> Self {
self.to = Some(to);
self
}
pub fn limit(mut self, limit: i64) -> Self {
self.limit = Some(limit);
self
}
}
impl ToQuery for SharesParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "from", &self.from);
push(&mut pairs, "to", &self.to);
push(&mut pairs, "limit", &self.limit);
pairs
}
}
#[derive(Debug, Clone, Default)]
pub struct RoundsParams {
pub limit: Option<i64>,
pub offset: Option<i64>,
}
impl RoundsParams {
pub fn new() -> Self {
Self::default()
}
pub fn limit(mut self, limit: i64) -> Self {
self.limit = Some(limit);
self
}
pub fn offset(mut self, offset: i64) -> Self {
self.offset = Some(offset);
self
}
}
impl ToQuery for RoundsParams {
fn to_query(&self) -> QueryPairs {
let mut pairs = QueryPairs::new();
push(&mut pairs, "limit", &self.limit);
push(&mut pairs, "offset", &self.offset);
pairs
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn omits_unset_parameters() {
let pairs = DiscoverParams::new().limit(5).to_query();
assert_eq!(pairs, vec![("limit", "5".to_string())]);
}
#[test]
fn encodes_enums_with_their_wire_values() {
let pairs = DiscoverParams::new()
.tab(DiscoverTab::Graduating)
.status(TokenStatus::Bonding)
.to_query();
assert_eq!(
pairs,
vec![
("tab", "graduating".to_string()),
("status", "bonding".to_string())
]
);
}
#[test]
fn always_sends_the_required_chart_parameters() {
let pairs = ChartDataParams::new("0xabc", "5", 1, 2).to_query();
assert_eq!(
pairs,
vec![
("tokenAddress", "0xabc".to_string()),
("interval", "5".to_string()),
("from", "1".to_string()),
("to", "2".to_string()),
]
);
}
}