application: library bounded context
This commit is contained in:
64
crates/application/src/library/search.rs
Normal file
64
crates/application/src/library/search.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use domain::errors::{DomainError, DomainResult};
|
||||
use domain::models::LibraryItem;
|
||||
use domain::value_objects::{ContentType, LibrarySearchFilter};
|
||||
|
||||
use super::deps::LibraryQueryDeps;
|
||||
use super::queries::SearchItemsQuery;
|
||||
|
||||
/// Search library items with filters. Returns `(items, total_count)`.
|
||||
pub async fn execute(
|
||||
deps: &LibraryQueryDeps,
|
||||
query: SearchItemsQuery,
|
||||
) -> DomainResult<(Vec<LibraryItem>, u32)> {
|
||||
let content_type = query
|
||||
.content_type
|
||||
.as_deref()
|
||||
.map(parse_content_type)
|
||||
.transpose()?;
|
||||
|
||||
let mut filter = LibrarySearchFilter::new()
|
||||
.with_offset(query.offset)
|
||||
.with_limit(query.limit);
|
||||
|
||||
if let Some(pid) = query.provider_id {
|
||||
filter = filter.with_provider_id(pid);
|
||||
}
|
||||
if let Some(ct) = content_type {
|
||||
filter = filter.with_content_type(ct);
|
||||
}
|
||||
if !query.genres.is_empty() {
|
||||
filter = filter.with_genres(query.genres);
|
||||
}
|
||||
if let Some(term) = query.search_term {
|
||||
filter = filter.with_search_term(term);
|
||||
}
|
||||
if let Some(cid) = query.collection_id {
|
||||
filter = filter.with_collection_id(cid);
|
||||
}
|
||||
if !query.series_names.is_empty() {
|
||||
filter = filter.with_series_names(query.series_names);
|
||||
}
|
||||
if let Some(sn) = query.season_number {
|
||||
filter = filter.with_season_number(sn);
|
||||
}
|
||||
if let Some(decade) = query.decade {
|
||||
filter = filter.with_decade(decade);
|
||||
}
|
||||
|
||||
deps.library_query.search(&filter).await
|
||||
}
|
||||
|
||||
fn parse_content_type(s: &str) -> DomainResult<ContentType> {
|
||||
match s {
|
||||
"movie" => Ok(ContentType::Movie),
|
||||
"episode" => Ok(ContentType::Episode),
|
||||
"short" => Ok(ContentType::Short),
|
||||
other => Err(DomainError::ValidationError(format!(
|
||||
"Unknown content type '{other}'. Use movie, episode, or short."
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "tests/search.rs"]
|
||||
mod tests;
|
||||
Reference in New Issue
Block a user