Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 9 additions & 86 deletions crates/graphql-api/src/objects/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use crate::{
sortable_fields::{PlayerMapRankingSortableField, UnorderedRecordSortableField},
},
utils::{
connection_input::{ConnectionInput, ConnectionInputBuilder},
page_input::{PaginationInput, apply_cursor_input},
pagination_result::{PaginationResult, get_paginated},
records_filter::apply_filter,
Expand Down Expand Up @@ -327,14 +328,15 @@ impl QueryRoot {
first,
last,
|after, before, first, last| async move {
let input = <PlayersConnectionInput>::new(ConnectionParameters {
let input = ConnectionInputBuilder::new(ConnectionParameters {
after,
before,
first,
last,
})
.with_filter(filter)
.with_sort(sort);
.with_sort(sort)
.build(player_ranking());

get_players_connection(&db.sql_conn, &mut redis_conn, input).await
},
Expand Down Expand Up @@ -363,14 +365,15 @@ impl QueryRoot {
first,
last,
|after, before, first, last| async move {
let input = <MapsConnectionInput>::new(ConnectionParameters {
let input = ConnectionInputBuilder::new(ConnectionParameters {
after,
before,
first,
last,
})
.with_filter(filter)
.with_sort(sort);
.with_sort(sort)
.build(map_ranking());

get_maps_connection(&db.sql_conn, &mut redis_conn, input).await
},
Expand Down Expand Up @@ -422,84 +425,6 @@ impl QueryRoot {
}
}

enum EitherRedisKey<A, B> {
A(A),
B(B),
}

impl<A, B> ToRedisArgs for EitherRedisKey<A, B>
where
A: ToRedisArgs,
B: ToRedisArgs,
{
fn write_redis_args<W>(&self, out: &mut W)
where
W: ?Sized + deadpool_redis::redis::RedisWrite,
{
match self {
EitherRedisKey::A(a) => ToRedisArgs::write_redis_args(a, out),
EitherRedisKey::B(b) => ToRedisArgs::write_redis_args(b, out),
}
}
}

fn custom_source_or<S, F, D>(source: Option<S>, default: F) -> EitherRedisKey<D, S>
where
F: FnOnce() -> D,
{
source
.map(EitherRedisKey::B)
.unwrap_or_else(|| EitherRedisKey::A(default()))
}

pub(crate) struct ConnectionInput<C, F, O, S> {
connection_parameters: ConnectionParameters<C>,
filter: Option<F>,
sort: Option<O>,
source: Option<S>,
}

// derive(Default) adds Default: bound to the generics
impl<C, F, O, S> Default for ConnectionInput<C, F, O, S> {
fn default() -> Self {
Self {
connection_parameters: Default::default(),
filter: Default::default(),
sort: Default::default(),
source: Default::default(),
}
}
}

impl<C, F, O, S> ConnectionInput<C, F, O, S> {
pub(crate) fn new(connection_parameters: ConnectionParameters<C>) -> Self {
Self {
connection_parameters,
..Default::default()
}
}

pub(crate) fn with_filter(mut self, filter: Option<F>) -> Self {
self.filter = filter;
self
}

pub(crate) fn with_sort(mut self, sort: Option<O>) -> Self {
self.sort = sort;
self
}

#[allow(unused)] // used for testing
pub(crate) fn with_source<U>(self, source: U) -> ConnectionInput<C, F, O, U> {
ConnectionInput {
connection_parameters: self.connection_parameters,
filter: self.filter,
sort: self.sort,
source: Some(source),
}
}
}

pub(crate) enum PlayerMapRankingCursor {
Name(TextCursor),
Score(F64Cursor),
Expand Down Expand Up @@ -656,10 +581,9 @@ where
} = get_paginated(conn, query, &pagination_input).await?;

connection.edges.reserve(players.len());
let source = custom_source_or(input.source, player_ranking);

for player in players {
let rank: i32 = redis_conn.zrevrank(&source, player.player.id).await?;
let rank: i32 = redis_conn.zrevrank(&input.source, player.player.id).await?;
connection.edges.push(connection::Edge::new(
ID((cursor_encoder)(&player)),
PlayerWithScore {
Expand Down Expand Up @@ -787,10 +711,9 @@ where
} = get_paginated(conn, query, &pagination_input).await?;

connection.edges.reserve(maps.len());
let source = custom_source_or(input.source, map_ranking);

for map in maps {
let rank: i32 = redis_conn.zrevrank(&source, map.map.id).await?;
let rank: i32 = redis_conn.zrevrank(&input.source, map.map.id).await?;
connection.edges.push(connection::Edge::new(
ID((cursor_encoder)(&map)),
MapWithScore {
Expand Down
13 changes: 7 additions & 6 deletions crates/graphql-api/src/tests/queryroot_maps_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use sea_orm::{ActiveValue::Set, EntityTrait};
use crate::{
config::InitError,
cursors::{ConnectionParameters, F64Cursor},
objects::root::{MapsConnectionInput, get_maps_connection},
objects::root::get_maps_connection,
utils::connection_input::ConnectionInputBuilder,
};

fn setup() {
Expand Down Expand Up @@ -116,7 +117,7 @@ async fn default_page() -> anyhow::Result<()> {
let result = get_maps_connection(
&db.sql_conn,
&mut redis_conn,
<MapsConnectionInput>::default().with_source(source),
ConnectionInputBuilder::default().build(source),
)
.await?;

Expand Down Expand Up @@ -225,7 +226,7 @@ async fn test_first_x_after_y(
let result = get_maps_connection(
&db.sql_conn,
&mut redis_conn,
<MapsConnectionInput>::new(ConnectionParameters {
ConnectionInputBuilder::new(ConnectionParameters {
first: params.first,
after: Some(
F64Cursor {
Expand All @@ -236,7 +237,7 @@ async fn test_first_x_after_y(
),
..Default::default()
})
.with_source(source),
.build(source),
)
.await?;

Expand Down Expand Up @@ -343,7 +344,7 @@ async fn test_last_x_before_y(
let result = get_maps_connection(
&db.sql_conn,
&mut redis_conn,
<MapsConnectionInput>::new(ConnectionParameters {
ConnectionInputBuilder::new(ConnectionParameters {
last: params.last,
before: Some(
F64Cursor {
Expand All @@ -354,7 +355,7 @@ async fn test_last_x_before_y(
),
..Default::default()
})
.with_source(source),
.build(source),
)
.await?;

Expand Down
13 changes: 7 additions & 6 deletions crates/graphql-api/src/tests/queryroot_players_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use sea_orm::{ActiveValue::Set, EntityTrait};
use crate::{
config::InitError,
cursors::{ConnectionParameters, F64Cursor},
objects::root::{PlayersConnectionInput, get_players_connection},
objects::root::get_players_connection,
utils::connection_input::ConnectionInputBuilder,
};

fn setup() {
Expand Down Expand Up @@ -109,7 +110,7 @@ async fn default_page() -> anyhow::Result<()> {
let result = get_players_connection(
&db.sql_conn,
&mut redis_conn,
<PlayersConnectionInput>::default().with_source(source),
ConnectionInputBuilder::default().build(source),
)
.await?;

Expand Down Expand Up @@ -211,7 +212,7 @@ async fn test_first_x_after_y(
let result = get_players_connection(
&db.sql_conn,
&mut redis_conn,
<PlayersConnectionInput>::new(ConnectionParameters {
ConnectionInputBuilder::new(ConnectionParameters {
first: params.first,
after: Some(
F64Cursor {
Expand All @@ -222,7 +223,7 @@ async fn test_first_x_after_y(
),
..Default::default()
})
.with_source(source),
.build(source),
)
.await?;

Expand Down Expand Up @@ -321,7 +322,7 @@ async fn test_last_x_before_y(
let result = get_players_connection(
&db.sql_conn,
&mut redis_conn,
<PlayersConnectionInput>::new(ConnectionParameters {
ConnectionInputBuilder::new(ConnectionParameters {
last: params.last,
before: Some(
F64Cursor {
Expand All @@ -332,7 +333,7 @@ async fn test_last_x_before_y(
),
..Default::default()
})
.with_source(source),
.build(source),
)
.await?;

Expand Down
53 changes: 53 additions & 0 deletions crates/graphql-api/src/utils/connection_input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::cursors::ConnectionParameters;

pub(crate) struct ConnectionInputBuilder<C, F, S> {
connection_parameters: ConnectionParameters<C>,
filter: Option<F>,
sort: Option<S>,
}

// derive(Default) adds Default: bound to the generics
impl<C, F, S> Default for ConnectionInputBuilder<C, F, S> {
fn default() -> Self {
Self {
connection_parameters: Default::default(),
filter: Default::default(),
sort: Default::default(),
}
}
}

impl<C, F, S> ConnectionInputBuilder<C, F, S> {
pub(crate) fn new(connection_parameters: ConnectionParameters<C>) -> Self {
Self {
connection_parameters,
..Default::default()
}
}

pub(crate) fn with_filter(mut self, filter: Option<F>) -> Self {
self.filter = filter;
self
}

pub(crate) fn with_sort(mut self, sort: Option<S>) -> Self {
self.sort = sort;
self
}

pub(crate) fn build<Src>(self, source: Src) -> ConnectionInput<C, F, S, Src> {
ConnectionInput {
connection_parameters: self.connection_parameters,
filter: self.filter,
sort: self.sort,
source,
}
}
}

pub(crate) struct ConnectionInput<C, F, S, Src> {
pub(crate) connection_parameters: ConnectionParameters<C>,
pub(crate) filter: Option<F>,
pub(crate) sort: Option<S>,
pub(crate) source: Src,
}
1 change: 1 addition & 0 deletions crates/graphql-api/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod connection_input;
pub mod page_input;
pub mod pagination_result;
pub mod records_filter;
Loading