From d8e4636b10ab36ecd44df134d9ef1230a7443ab1 Mon Sep 17 00:00:00 2001 From: Tyler Buchea Date: Sat, 28 Feb 2026 21:26:28 -0400 Subject: [PATCH] feat: add --descending flag to all list commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The --ascending flag was the only sort direction control, but omitting it just deferred to the API default — there was no way to explicitly request descending sort. Add a --descending counterpart (mutually exclusive via conflicts_with) so users can opt into either direction. No flag omits the parameter entirely, preserving existing behavior. Closes #17 Co-Authored-By: Claude Opus 4.6 --- src/commands/comments.rs | 34 +++++++++++++++---- src/commands/events.rs | 16 +++++++-- src/commands/markets.rs | 72 ++++++++++++++++++++++++++++++++++++++-- src/commands/series.rs | 17 ++++++++-- src/commands/sports.rs | 17 ++++++++-- src/commands/tags.rs | 17 ++++++++-- 6 files changed, 152 insertions(+), 21 deletions(-) diff --git a/src/commands/comments.rs b/src/commands/comments.rs index 9c55fad..8921506 100644 --- a/src/commands/comments.rs +++ b/src/commands/comments.rs @@ -41,9 +41,13 @@ pub enum CommentsCommand { #[arg(long)] order: Option, - /// Sort ascending instead of descending - #[arg(long)] + /// Sort ascending + #[arg(long, conflicts_with = "descending")] ascending: bool, + + /// Sort descending + #[arg(long, conflicts_with = "ascending")] + descending: bool, }, /// Get a comment by ID @@ -69,9 +73,13 @@ pub enum CommentsCommand { #[arg(long)] order: Option, - /// Sort ascending instead of descending - #[arg(long)] + /// Sort ascending + #[arg(long, conflicts_with = "descending")] ascending: bool, + + /// Sort descending + #[arg(long, conflicts_with = "ascending")] + descending: bool, }, } @@ -105,14 +113,21 @@ pub async fn execute( offset, order, ascending, + descending, } => { + let sort_ascending = match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + }; + let request = CommentsRequest::builder() .parent_entity_type(ParentEntityType::from(entity_type)) .parent_entity_id(entity_id) .limit(limit) .maybe_offset(offset) .maybe_order(order) - .maybe_ascending(if ascending { Some(true) } else { None }) + .maybe_ascending(sort_ascending) .build(); let comments = client.comments(&request).await?; @@ -143,14 +158,21 @@ pub async fn execute( offset, order, ascending, + descending, } => { + let sort_ascending = match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + }; + let addr = parse_address(&address)?; let request = CommentsByUserAddressRequest::builder() .user_address(addr) .limit(limit) .maybe_offset(offset) .maybe_order(order) - .maybe_ascending(if ascending { Some(true) } else { None }) + .maybe_ascending(sort_ascending) .build(); let comments = client.comments_by_user_address(&request).await?; diff --git a/src/commands/events.rs b/src/commands/events.rs index b5d947a..4d64086 100644 --- a/src/commands/events.rs +++ b/src/commands/events.rs @@ -40,10 +40,14 @@ pub enum EventsCommand { #[arg(long)] order: Option, - /// Sort ascending instead of descending - #[arg(long)] + /// Sort ascending + #[arg(long, conflicts_with = "descending")] ascending: bool, + /// Sort descending + #[arg(long, conflicts_with = "ascending")] + descending: bool, + /// Filter by tag slug (e.g. "politics", "crypto") #[arg(long)] tag: Option, @@ -71,15 +75,21 @@ pub async fn execute(client: &gamma::Client, args: EventsArgs, output: OutputFor offset, order, ascending, + descending, tag, } => { let resolved_closed = closed.or_else(|| active.map(|a| !a)); + let sort_ascending = match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + }; let request = EventsRequest::builder() .limit(limit) .maybe_closed(resolved_closed) .maybe_offset(offset) - .maybe_ascending(if ascending { Some(true) } else { None }) + .maybe_ascending(sort_ascending) .maybe_tag_slug(tag) .order(order.into_iter().collect::>()) .build(); diff --git a/src/commands/markets.rs b/src/commands/markets.rs index 68e5491..7318aac 100644 --- a/src/commands/markets.rs +++ b/src/commands/markets.rs @@ -46,9 +46,13 @@ pub enum MarketsCommand { #[arg(long)] order: Option, - /// Sort ascending instead of descending - #[arg(long)] + /// Sort ascending + #[arg(long, conflicts_with = "descending")] ascending: bool, + + /// Sort descending + #[arg(long, conflicts_with = "ascending")] + descending: bool, }, /// Get a single market by ID or slug @@ -87,15 +91,21 @@ pub async fn execute( offset, order, ascending, + descending, } => { let resolved_closed = closed.or_else(|| active.map(|a| !a)); + let sort_ascending = match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + }; let request = MarketsRequest::builder() .limit(limit) .maybe_closed(resolved_closed) .maybe_offset(offset) .maybe_order(order) - .maybe_ascending(if ascending { Some(true) } else { None }) + .maybe_ascending(sort_ascending) .build(); let markets = client.markets(&request).await?; @@ -156,3 +166,59 @@ pub async fn execute( Ok(()) } + +#[cfg(test)] +mod tests { + use polymarket_client_sdk::gamma::types::request::MarketsRequest; + use polymarket_client_sdk::ToQueryParams; + + fn resolve_sort(ascending: bool, descending: bool) -> Option { + match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + } + } + + #[test] + fn no_flag_omits_ascending_param() { + let sort = resolve_sort(false, false); + let request = MarketsRequest::builder() + .limit(25) + .maybe_ascending(sort) + .build(); + let qs = request.query_params(None); + assert!( + !qs.contains("ascending"), + "expected ascending param to be omitted, got: {qs}" + ); + } + + #[test] + fn ascending_flag_sends_true() { + let sort = resolve_sort(true, false); + let request = MarketsRequest::builder() + .limit(25) + .maybe_ascending(sort) + .build(); + let qs = request.query_params(None); + assert!( + qs.contains("ascending=true"), + "expected ascending=true, got: {qs}" + ); + } + + #[test] + fn descending_flag_sends_false() { + let sort = resolve_sort(false, true); + let request = MarketsRequest::builder() + .limit(25) + .maybe_ascending(sort) + .build(); + let qs = request.query_params(None); + assert!( + qs.contains("ascending=false"), + "expected ascending=false, got: {qs}" + ); + } +} diff --git a/src/commands/series.rs b/src/commands/series.rs index 11dba91..7444bed 100644 --- a/src/commands/series.rs +++ b/src/commands/series.rs @@ -30,10 +30,14 @@ pub enum SeriesCommand { #[arg(long)] order: Option, - /// Sort ascending instead of descending - #[arg(long)] + /// Sort ascending + #[arg(long, conflicts_with = "descending")] ascending: bool, + /// Sort descending + #[arg(long, conflicts_with = "ascending")] + descending: bool, + /// Filter by closed status #[arg(long)] closed: Option, @@ -53,13 +57,20 @@ pub async fn execute(client: &gamma::Client, args: SeriesArgs, output: OutputFor offset, order, ascending, + descending, closed, } => { + let sort_ascending = match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + }; + let request = SeriesListRequest::builder() .limit(limit) .maybe_offset(offset) .maybe_order(order) - .maybe_ascending(if ascending { Some(true) } else { None }) + .maybe_ascending(sort_ascending) .maybe_closed(closed) .build(); diff --git a/src/commands/sports.rs b/src/commands/sports.rs index 8f46c72..2075ec8 100644 --- a/src/commands/sports.rs +++ b/src/commands/sports.rs @@ -33,10 +33,14 @@ pub enum SportsCommand { #[arg(long)] order: Option, - /// Sort ascending instead of descending - #[arg(long)] + /// Sort ascending + #[arg(long, conflicts_with = "descending")] ascending: bool, + /// Sort descending + #[arg(long, conflicts_with = "ascending")] + descending: bool, + /// Filter by league #[arg(long)] league: Option, @@ -68,13 +72,20 @@ pub async fn execute(client: &gamma::Client, args: SportsArgs, output: OutputFor offset, order, ascending, + descending, league, } => { + let sort_ascending = match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + }; + let request = TeamsRequest::builder() .limit(limit) .maybe_offset(offset) .maybe_order(order) - .maybe_ascending(if ascending { Some(true) } else { None }) + .maybe_ascending(sort_ascending) .league(league.into_iter().collect::>()) .build(); diff --git a/src/commands/tags.rs b/src/commands/tags.rs index 537a2ff..ff10409 100644 --- a/src/commands/tags.rs +++ b/src/commands/tags.rs @@ -30,9 +30,13 @@ pub enum TagsCommand { #[arg(long)] offset: Option, - /// Sort ascending instead of descending - #[arg(long)] + /// Sort ascending + #[arg(long, conflicts_with = "descending")] ascending: bool, + + /// Sort descending + #[arg(long, conflicts_with = "ascending")] + descending: bool, }, /// Get a single tag by ID or slug @@ -68,11 +72,18 @@ pub async fn execute(client: &gamma::Client, args: TagsArgs, output: OutputForma limit, offset, ascending, + descending, } => { + let sort_ascending = match (ascending, descending) { + (true, _) => Some(true), + (_, true) => Some(false), + _ => None, + }; + let request = TagsRequest::builder() .limit(limit) .maybe_offset(offset) - .maybe_ascending(if ascending { Some(true) } else { None }) + .maybe_ascending(sort_ascending) .build(); let tags = client.tags(&request).await?;