Skip to content
6 changes: 3 additions & 3 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@ get_all_tasks_1: |-
.unwrap();
get_all_tasks_filtering_1: |-
let mut query = TasksQuery::new(&client)
.with_index_uid(["movies"])
.with_index_uids(["movies"])
.execute()
.await
.unwrap();
get_all_tasks_filtering_2: |-
let mut query = TasksQuery::new(&client)
.with_status(["succeeded", "failed"])
.with_type(["documentAdditionOrUpdate"])
.with_statuses(["succeeded", "failed"])
.with_types(["documentAdditionOrUpdate"])
.execute()
.await
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ WARNING: `meilisearch-sdk` will panic if no Window is available (ex: Web extensi

## 🤖 Compatibility with Meilisearch

This package only guarantees the compatibility with the [version v0.29.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.29.0).
This package only guarantees the compatibility with the [version v0.30.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.30.0).

## ⚙️ Contributing

Expand Down
2 changes: 1 addition & 1 deletion README.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ WARNING: `meilisearch-sdk` will panic if no Window is available (ex: Web extensi

## 🤖 Compatibility with Meilisearch

This package only guarantees the compatibility with the [version v0.29.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.29.0).
This package only guarantees the compatibility with the [version v0.30.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.30.0).

## ⚙️ Contributing

Expand Down
6 changes: 3 additions & 3 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ impl Client {
/// # let client = client::Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
///
/// let mut query = tasks::TasksQuery::new(&client);
/// query.with_index_uid(["get_tasks_with"]);
/// query.with_index_uids(["get_tasks_with"]);
/// let tasks = client.get_tasks_with(&query).await.unwrap();
/// # });
/// ```
Expand Down Expand Up @@ -930,15 +930,15 @@ mod tests {
#[meilisearch_test]
async fn test_get_tasks(client: Client) {
let tasks = client.get_tasks().await.unwrap();
assert!(tasks.results.len() >= 2);
assert!(tasks.limit == 20);
}

#[meilisearch_test]
async fn test_get_tasks_with_params(client: Client) {
let query = TasksQuery::new(&client);
let tasks = client.get_tasks_with(&query).await.unwrap();

assert!(tasks.results.len() >= 2);
assert!(tasks.limit == 20);
}

#[meilisearch_test]
Expand Down
6 changes: 6 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ pub enum ErrorCode {
InvalidApiKeyIndexes,
InvalidApiKeyExpiresAt,
ApiKeyNotFound,
InvalidTaskTypesFilter,
InvalidTaskStatusesFilter,
InvalidTaskCanceledByFilter,
InvalidTaskUidsFilter,
InvalidTaskDateFilter,
MissingTaskFilters,

/// That's unexpected. Please open a GitHub issue after ensuring you are
/// using the supported version of the Meilisearch server.
Expand Down
9 changes: 5 additions & 4 deletions src/indexes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,8 @@ impl Index {
///
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
/// let movie_index = client.index("get_documents");
///
/// let movie_index = client.index("get_documents_with");
///
/// # movie_index.add_or_replace(&[Movie{name:String::from("Interstellar"), description:String::from("Interstellar chronicles the adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.")}], Some("name")).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
///
Expand Down Expand Up @@ -902,7 +903,7 @@ impl Index {
/// ```
pub async fn get_tasks(&self) -> Result<TasksResults, Error> {
let mut query = TasksQuery::new(&self.client);
query.with_index_uid([self.uid.as_str()]);
query.with_index_uids([self.uid.as_str()]);

self.client.get_tasks_with(&query).await
}
Expand All @@ -923,7 +924,7 @@ impl Index {
/// # let index = client.create_index("get_tasks_with", None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap().try_make_index(&client).unwrap();
///
/// let mut query = TasksQuery::new(&client);
/// query.with_index_uid(["none_existant"]);
/// query.with_index_uids(["none_existant"]);
/// let tasks = index.get_tasks_with(&query).await.unwrap();
///
/// assert!(tasks.results.len() > 0);
Expand All @@ -935,7 +936,7 @@ impl Index {
tasks_query: &TasksQuery<'_>,
) -> Result<TasksResults, Error> {
let mut query = tasks_query.clone();
query.with_index_uid([self.uid.as_str()]);
query.with_index_uids([self.uid.as_str()]);

self.client.get_tasks_with(&query).await
}
Expand Down
215 changes: 187 additions & 28 deletions src/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,13 +406,52 @@ pub struct TasksQuery<'a> {
pub client: &'a Client,
// Index uids array to only retrieve the tasks of the indexes.
#[serde(skip_serializing_if = "Option::is_none")]
pub index_uid: Option<Vec<&'a str>>,
pub index_uids: Option<Vec<&'a str>>,
// Statuses array to only retrieve the tasks with these statuses.
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<Vec<&'a str>>,
pub statuses: Option<Vec<&'a str>>,
// Types array to only retrieve the tasks with these [TaskType].
#[serde(skip_serializing_if = "Option::is_none", rename = "type")]
pub task_type: Option<Vec<&'a str>>,
#[serde(skip_serializing_if = "Option::is_none", rename = "types")]
pub task_types: Option<Vec<&'a str>>,
// Uids of the tasks to retrieve
#[serde(skip_serializing_if = "Option::is_none")]
pub uids: Option<Vec<&'a u32>>,
// Date to retrieve all tasks that were enqueued before it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub before_enqueued_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were enqueued after it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub after_enqueued_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were started before it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub before_started_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were started after it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub after_started_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were finished before it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub before_finished_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were finished after it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub after_finished_at: Option<OffsetDateTime>,
// Maximum number of tasks to return
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
Expand All @@ -426,32 +465,88 @@ impl<'a> TasksQuery<'a> {
pub fn new(client: &'a Client) -> TasksQuery<'a> {
TasksQuery {
client,
index_uid: None,
status: None,
task_type: None,
index_uids: None,
statuses: None,
task_types: None,
limit: None,
from: None,
uids: None,
before_enqueued_at: None,
after_enqueued_at: None,
before_started_at: None,
after_started_at: None,
before_finished_at: None,
after_finished_at: None,
}
}
pub fn with_index_uid<'b>(
pub fn with_index_uids<'b>(
&'b mut self,
index_uids: impl IntoIterator<Item = &'a str>,
) -> &'b mut TasksQuery<'a> {
self.index_uids = Some(index_uids.into_iter().collect());
self
}
pub fn with_statuses<'b>(
&'b mut self,
statuses: impl IntoIterator<Item = &'a str>,
) -> &'b mut TasksQuery<'a> {
self.statuses = Some(statuses.into_iter().collect());
self
}
pub fn with_types<'b>(
&'b mut self,
task_types: impl IntoIterator<Item = &'a str>,
) -> &'b mut TasksQuery<'a> {
self.task_types = Some(task_types.into_iter().collect());
self
}
pub fn with_uids<'b>(
&'b mut self,
uids: impl IntoIterator<Item = &'a u32>,
) -> &'b mut TasksQuery<'a> {
self.uids = Some(uids.into_iter().collect());
self
}
pub fn with_before_enqueued_at<'b>(
&'b mut self,
index_uid: impl IntoIterator<Item = &'a str>,
before_enqueued_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.index_uid = Some(index_uid.into_iter().collect());
self.before_enqueued_at = Some(*before_enqueued_at);
self
}
pub fn with_status<'b>(
pub fn with_after_enqueued_at<'b>(
&'b mut self,
status: impl IntoIterator<Item = &'a str>,
after_enqueued_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.status = Some(status.into_iter().collect());
self.after_enqueued_at = Some(*after_enqueued_at);
self
}
pub fn with_type<'b>(
pub fn with_before_started_at<'b>(
&'b mut self,
task_type: impl IntoIterator<Item = &'a str>,
before_started_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.task_type = Some(task_type.into_iter().collect());
self.before_started_at = Some(*before_started_at);
self
}
pub fn with_after_started_at<'b>(
&'b mut self,
after_started_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.after_started_at = Some(*after_started_at);
self
}
pub fn with_before_finished_at<'b>(
&'b mut self,
before_finished_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.before_finished_at = Some(*before_finished_at);
self
}
pub fn with_after_finished_at<'b>(
&'b mut self,
after_finished_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.after_finished_at = Some(*after_finished_at);
self
}
pub fn with_limit<'b>(&'b mut self, limit: u32) -> &'b mut TasksQuery<'a> {
Expand Down Expand Up @@ -640,17 +735,81 @@ mod test {
let mock_server_url = &mockito::server_url();
let client = Client::new(mock_server_url, "masterKey");
let path =
"/tasks?indexUid=movies,test&status=equeued&type=documentDeletion&limit=0&from=1";
"/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion&uids=1&limit=0&from=1";

let mock_res = mock("GET", path).with_status(200).create();

let mut query = TasksQuery::new(&client);
query
.with_index_uid(["movies", "test"])
.with_status(["equeued"])
.with_type(["documentDeletion"])
.with_index_uids(["movies", "test"])
.with_statuses(["equeued"])
.with_types(["documentDeletion"])
.with_from(1)
.with_limit(0);
.with_limit(0)
.with_uids([&1]);

let _ = client.get_tasks_with(&query).await;

mock_res.assert();
Ok(())
}

#[meilisearch_test]
async fn test_get_tasks_with_date_params() -> Result<(), Error> {
let mock_server_url = &mockito::server_url();
let client = Client::new(mock_server_url, "masterKey");
let path = "/tasks?\
beforeEnqueuedAt=2022-02-03T13%3A02%3A38.369634Z\
&afterEnqueuedAt=2023-02-03T13%3A02%3A38.369634Z\
&beforeStartedAt=2024-02-03T13%3A02%3A38.369634Z\
&afterStartedAt=2025-02-03T13%3A02%3A38.369634Z\
&beforeFinishedAt=2026-02-03T13%3A02%3A38.369634Z\
&afterFinishedAt=2027-02-03T13%3A02%3A38.369634Z";

let mock_res = mock("GET", path).with_status(200).create();

let before_enqueued_at = OffsetDateTime::parse(
"2022-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();
let after_enqueued_at = OffsetDateTime::parse(
"2023-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();
let before_started_at = OffsetDateTime::parse(
"2024-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let after_started_at = OffsetDateTime::parse(
"2025-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let before_finished_at = OffsetDateTime::parse(
"2026-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let after_finished_at = OffsetDateTime::parse(
"2027-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let mut query = TasksQuery::new(&client);
query
.with_before_enqueued_at(&before_enqueued_at)
.with_after_enqueued_at(&after_enqueued_at)
.with_before_started_at(&before_started_at)
.with_after_started_at(&after_started_at)
.with_before_finished_at(&before_finished_at)
.with_after_finished_at(&after_finished_at);

let _ = client.get_tasks_with(&query).await;

Expand All @@ -662,15 +821,15 @@ mod test {
async fn test_get_tasks_on_struct_with_params() -> Result<(), Error> {
let mock_server_url = &mockito::server_url();
let client = Client::new(mock_server_url, "masterKey");
let path = "/tasks?indexUid=movies,test&status=equeued&type=documentDeletion";
let path = "/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion";

let mock_res = mock("GET", path).with_status(200).create();

let mut query = TasksQuery::new(&client);
let _ = query
.with_index_uid(["movies", "test"])
.with_status(["equeued"])
.with_type(["documentDeletion"])
.with_index_uids(["movies", "test"])
.with_statuses(["equeued"])
.with_types(["documentDeletion"])
.execute()
.await;

Expand All @@ -680,9 +839,9 @@ mod test {
}

#[meilisearch_test]
async fn test_get_tasks_with_none_existant_index_uid(client: Client) -> Result<(), Error> {
async fn test_get_tasks_with_none_existant_index_uids(client: Client) -> Result<(), Error> {
let mut query = TasksQuery::new(&client);
query.with_index_uid(["no_name"]);
query.with_index_uids(["no_name"]);
let tasks = client.get_tasks_with(&query).await.unwrap();

assert_eq!(tasks.results.len(), 0);
Expand All @@ -692,7 +851,7 @@ mod test {
#[meilisearch_test]
async fn test_get_tasks_with_execute(client: Client) -> Result<(), Error> {
let tasks = TasksQuery::new(&client)
.with_index_uid(["no_name"])
.with_index_uids(["no_name"])
.execute()
.await
.unwrap();
Expand Down