From daeb5311840680599a0ce6e49d181b9289010f68 Mon Sep 17 00:00:00 2001 From: rtkay123 Date: Wed, 1 Apr 2026 09:05:33 +0200 Subject: feat(schema): cursor pagination --- lib/warden-core/src/config/cli/database.rs | 2 +- lib/warden-core/src/error.rs | 4 +++ lib/warden-core/src/lib.rs | 1 + lib/warden-core/src/pagination/mod.rs | 58 ++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 lib/warden-core/src/pagination/mod.rs (limited to 'lib/warden-core/src') diff --git a/lib/warden-core/src/config/cli/database.rs b/lib/warden-core/src/config/cli/database.rs index 31ba930..70bf600 100644 --- a/lib/warden-core/src/config/cli/database.rs +++ b/lib/warden-core/src/config/cli/database.rs @@ -117,7 +117,7 @@ impl Database { } let host = "localhost".to_owned(); - let host = self.database_host.as_ref().unwrap_or_else(|| &host); + let host = self.database_host.as_ref().unwrap_or(&host); let mut url = Url::parse(&format!("postgres://{host}"))?; if let Some(ref u) = self.database_username { diff --git a/lib/warden-core/src/error.rs b/lib/warden-core/src/error.rs index d90a862..e347407 100644 --- a/lib/warden-core/src/error.rs +++ b/lib/warden-core/src/error.rs @@ -8,6 +8,10 @@ pub enum WardenError { Migration(#[from] sqlx::migrate::MigrateError), #[error(transparent)] Url(#[from] url::ParseError), + #[error(transparent)] + Pagination(#[from] base64::DecodeError), + #[error(transparent)] + PaginationCursor(#[from] std::string::FromUtf8Error), #[error("Missing required configuration values:\n`{0}`")] Config(String), #[error("invalid header (expected {expected:?}, found {found:?})")] diff --git a/lib/warden-core/src/lib.rs b/lib/warden-core/src/lib.rs index f200ba1..627659e 100644 --- a/lib/warden-core/src/lib.rs +++ b/lib/warden-core/src/lib.rs @@ -1,3 +1,4 @@ mod error; pub use error::WardenError; pub mod config; +pub mod pagination; diff --git a/lib/warden-core/src/pagination/mod.rs b/lib/warden-core/src/pagination/mod.rs new file mode 100644 index 0000000..25fb083 --- /dev/null +++ b/lib/warden-core/src/pagination/mod.rs @@ -0,0 +1,58 @@ +use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; + +/// Arguments used for cursor-based pagination. +#[derive(Deserialize, Debug, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct PaginationArgs { + /// Returns the first `n` items from the list. + pub first: Option, + + /// A cursor pointing to the position after which items should be returned. + pub after: Option, + + /// Returns the last `n` items from the list. + pub last: Option, + + /// A cursor pointing to the position before which items should be returned. + pub before: Option, +} + +/// Metadata describing the current page of results. +#[derive(Serialize, Debug, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct PageInfo { + /// Indicates whether there are more items when paginating forward. + pub has_next_page: bool, + + /// Indicates whether there are more items when paginating backward. + pub has_previous_page: bool, + + /// The cursor corresponding to the first item in the current page. + pub start_cursor: Option, + + /// The cursor corresponding to the last item in the current page. + pub end_cursor: Option, +} + +/// A paginated connection containing edges and pagination metadata. +#[derive(Serialize, Debug, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct Connection { + /// A list of edges, each containing a node and its cursor. + pub edges: Vec>, + + /// Information about pagination for this connection. + pub page_info: PageInfo, +} + +/// An edge in a connection, representing a node and its cursor. +#[derive(Serialize, Debug, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct Edge { + /// The item/node contained in this edge. + pub node: T, + + /// A cursor for this node, used in pagination. + pub cursor: String, +} -- cgit v1.2.3