feat: Add pagination support to ListMediaParams and ListMediaOptions
This commit is contained in:
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,4 +87,4 @@ impl FromRequestParts<AppState> for ApiListMediaOptions {
|
||||
|
||||
Ok(ApiListMediaOptions(params.into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user