Implement the StarOr on all the tasks filters

This commit is contained in:
Kerollmops 2022-05-30 17:12:53 +02:00
parent 082d6b89ff
commit 8800b348f0
No known key found for this signature in database
GPG Key ID: 92ADA4E935E71FA4
2 changed files with 52 additions and 24 deletions

View File

@ -22,8 +22,8 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
#[serde(rename_all = "camelCase", deny_unknown_fields)] #[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct TaskFilterQuery { pub struct TaskFilterQuery {
#[serde(rename = "type")] #[serde(rename = "type")]
type_: Option<CS<TaskType>>, type_: Option<CS<StarOr<TaskType>>>,
status: Option<CS<TaskStatus>>, status: Option<CS<StarOr<TaskStatus>>>,
index_uid: Option<CS<StarOr<IndexUid>>>, index_uid: Option<CS<StarOr<IndexUid>>>,
} }
@ -47,6 +47,20 @@ impl<T: FromStr> FromStr for StarOr<T> {
} }
} }
/// Extracts the raw values from the `StarOr` types and
/// return None if a `StarOr::Star` is encountered.
fn fold_star_or<T>(content: Vec<StarOr<T>>) -> Option<Vec<T>> {
content
.into_iter()
.fold(Some(Vec::new()), |acc, val| match (acc, val) {
(None, _) | (_, StarOr::Star) => None,
(Some(mut acc), StarOr::Other(uid)) => {
acc.push(uid);
Some(acc)
}
})
}
#[rustfmt::skip] #[rustfmt::skip]
fn task_type_matches_content(type_: &TaskType, content: &TaskContent) -> bool { fn task_type_matches_content(type_: &TaskType, content: &TaskContent) -> bool {
matches!((type_, content), matches!((type_, content),
@ -91,25 +105,14 @@ async fn get_tasks(
let search_rules = &meilisearch.filters().search_rules; let search_rules = &meilisearch.filters().search_rules;
// We first tranform a potential indexUid=* into a // We first tranform a potential indexUid=* into a "not specified indexUid filter"
// "not specified indexUid filter". // for every one of the filters: type, status, and indexUid.
let index_uid = let type_ = type_.map(CS::into_inner).and_then(fold_star_or);
match index_uid { let status = status.map(CS::into_inner).and_then(fold_star_or);
Some(indexes) => indexes let index_uid = index_uid.map(CS::into_inner).and_then(fold_star_or);
.into_inner()
.into_iter()
.fold(Some(Vec::new()), |acc, val| match (acc, val) {
(None, _) | (_, StarOr::Star) => None,
(Some(mut acc), StarOr::Other(uid)) => {
acc.push(uid);
Some(acc)
}
}),
None => None,
};
// Then we filter on potential indexes and make sure // Then we filter on potential indexes and make sure that the search filter
// that the search filter restrictions are also applied. // restrictions are also applied.
let indexes_filters = match index_uid { let indexes_filters = match index_uid {
Some(indexes) => { Some(indexes) => {
let mut filters = TaskFilter::default(); let mut filters = TaskFilter::default();
@ -135,7 +138,7 @@ async fn get_tasks(
// Then we complete the task filter with other potential status and types filters. // Then we complete the task filter with other potential status and types filters.
let filters = match (type_, status) { let filters = match (type_, status) {
(Some(CS(types)), Some(CS(statuses))) => { (Some(types), Some(statuses)) => {
let mut filters = indexes_filters.unwrap_or_default(); let mut filters = indexes_filters.unwrap_or_default();
filters.filter_fn(move |task| { filters.filter_fn(move |task| {
let matches_type = types let matches_type = types
@ -148,7 +151,7 @@ async fn get_tasks(
}); });
Some(filters) Some(filters)
} }
(Some(CS(types)), None) => { (Some(types), None) => {
let mut filters = indexes_filters.unwrap_or_default(); let mut filters = indexes_filters.unwrap_or_default();
filters.filter_fn(move |task| { filters.filter_fn(move |task| {
types types
@ -157,7 +160,7 @@ async fn get_tasks(
}); });
Some(filters) Some(filters)
} }
(None, Some(CS(statuses))) => { (None, Some(statuses)) => {
let mut filters = indexes_filters.unwrap_or_default(); let mut filters = indexes_filters.unwrap_or_default();
filters.filter_fn(move |task| { filters.filter_fn(move |task| {
statuses statuses

View File

@ -60,7 +60,7 @@ async fn list_tasks() {
} }
#[actix_rt::test] #[actix_rt::test]
async fn list_tasks_with_index_filter() { async fn list_tasks_with_star_filters() {
let server = Server::new().await; let server = Server::new().await;
let index = server.index("test"); let index = server.index("test");
index.create(None).await; index.create(None).await;
@ -82,6 +82,31 @@ async fn list_tasks_with_index_filter() {
let (response, code) = index.service.get("/tasks?indexUid=*,pasteque").await; let (response, code) = index.service.get("/tasks?indexUid=*,pasteque").await;
assert_eq!(code, 200); assert_eq!(code, 200);
assert_eq!(response["results"].as_array().unwrap().len(), 2); assert_eq!(response["results"].as_array().unwrap().len(), 2);
let (response, code) = index.service.get("/tasks?type=*").await;
assert_eq!(code, 200);
assert_eq!(response["results"].as_array().unwrap().len(), 2);
let (response, code) = index
.service
.get("/tasks?type=*,documentAdditionOrUpdate&status=*")
.await;
assert_eq!(code, 200, "{:?}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 2);
let (response, code) = index
.service
.get("/tasks?type=*,documentAdditionOrUpdate&status=*,failed&indexUid=test")
.await;
assert_eq!(code, 200, "{:?}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 2);
let (response, code) = index
.service
.get("/tasks?type=*,documentAdditionOrUpdate&status=*,failed&indexUid=test,*")
.await;
assert_eq!(code, 200, "{:?}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 2);
} }
#[actix_rt::test] #[actix_rt::test]