feat: Add pagination support to ListMediaParams and ListMediaOptions

This commit is contained in:
2025-11-15 17:54:00 +01:00
parent b80c4e0895
commit dd10211c63
4 changed files with 61 additions and 19 deletions

View File

@@ -1,10 +1,21 @@
use axum::{extract::{FromRequestParts, Query}, http::request::Parts};
use libertas_core::{error::CoreError, schema::{FilterParams, ListMediaOptions, MetadataFilter, SortOrder, SortParams}};
use axum::{
extract::{FromRequestParts, Query},
http::request::Parts,
};
use libertas_core::{
error::CoreError,
schema::{
FilterParams, ListMediaOptions, MetadataFilter, PaginationParams, SortOrder, SortParams,
},
};
use crate::{error::ApiError, schema::ListMediaParams, state::AppState};
pub struct ApiListMediaOptions(pub ListMediaOptions);
const DEFAULT_PAGE: u32 = 1;
const DEFAULT_LIMIT: u32 = 50;
impl From<ListMediaParams> for ListMediaOptions {
fn from(params: ListMediaParams) -> Self {
let sort = params.sort_by.map(|field| {
@@ -22,24 +33,44 @@ impl From<ListMediaParams> for ListMediaOptions {
None
} else {
Some(
params.metadata
.into_iter()
.filter_map(|s| {
s.split_once(":").map(|(key, value)| MetadataFilter {
tag_name: key.to_string(),
tag_value: value.to_string(),
params
.metadata
.into_iter()
.filter_map(|s| {
s.split_once(":").map(|(key, value)| MetadataFilter {
tag_name: key.to_string(),
tag_value: value.to_string(),
})
})
})
.collect::<Vec<_>>()
.collect::<Vec<_>>(),
)
};
let pagination = {
let page = params.page.unwrap_or(DEFAULT_PAGE);
let limit = params.limit.unwrap_or(DEFAULT_LIMIT);
let page = if page == 0 { DEFAULT_PAGE } else { page };
let limit = if limit > (DEFAULT_LIMIT * 2) {
DEFAULT_LIMIT * 2
} else {
limit
};
Some(PaginationParams { page, limit })
};
let filter = Some(FilterParams {
mime_type: params.mime_type,
metadata_filters,
});
ListMediaOptions { sort, filter }
ListMediaOptions {
sort,
filter,
pagination,
}
}
}

View File

@@ -37,6 +37,8 @@ pub struct ListMediaParams {
pub mime_type: Option<String>,
#[serde(default)]
pub metadata: Vec<String>,
pub page: Option<u32>,
pub limit: Option<u32>,
}
#[derive(Deserialize)]

View File

@@ -63,11 +63,17 @@ pub struct FilterParams {
// pub date_range: Option<(chrono::DateTime<chrono::Utc>, chrono::DateTime<chrono::Utc>)>,
}
#[derive(Debug, Clone, Copy)]
pub struct PaginationParams {
pub page: u32,
pub limit: u32,
}
#[derive(Debug, Clone)]
pub struct ListMediaOptions {
pub sort: Option<SortParams>,
pub filter: Option<FilterParams>,
// pub pagination: Option<PaginationParams>,
pub pagination: Option<PaginationParams>,
}
#[derive(Debug, Clone)]

View File

@@ -99,12 +99,15 @@ impl QueryBuilder<ListMediaOptions> for MediaQueryBuilder {
}
// --- 3. Apply Pagination (Future-Proofing Stub) ---
// if let Some(pagination) = &options.pagination {
// query.push(" LIMIT ");
// query.push_bind(pagination.limit);
// query.push(" OFFSET ");
// query.push_bind(pagination.offset);
// }
if let Some(pagination) = &options.pagination {
let limit = pagination.limit as i64;
let offset = (pagination.page.saturating_sub(1) as i64) * limit;
query.push(" LIMIT ");
query.push_bind(limit);
query.push(" OFFSET ");
query.push_bind(offset);
}
Ok(query)
}