meilisearch_sdk/
task_info.rs1use serde::Deserialize;
2use std::time::Duration;
3use time::OffsetDateTime;
4
5use crate::{client::Client, errors::Error, request::HttpClient, tasks::*};
6
7#[derive(Debug, Clone, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct TaskInfo {
10 #[serde(with = "time::serde::rfc3339")]
11 pub enqueued_at: OffsetDateTime,
12 pub index_uid: Option<String>,
13 pub status: String,
14 #[serde(flatten)]
15 pub update_type: TaskType,
16 pub task_uid: u32,
17}
18
19impl AsRef<u32> for TaskInfo {
20 fn as_ref(&self) -> &u32 {
21 &self.task_uid
22 }
23}
24
25impl TaskInfo {
26 #[must_use]
27 pub fn get_task_uid(&self) -> u32 {
28 self.task_uid
29 }
30
31 pub async fn wait_for_completion<Http: HttpClient>(
76 self,
77 client: &Client<Http>,
78 interval: Option<Duration>,
79 timeout: Option<Duration>,
80 ) -> Result<Task, Error> {
81 client.wait_for_task(self, interval, timeout).await
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use super::*;
88 use crate::{
89 client::*,
90 errors::{ErrorCode, ErrorType},
91 indexes::Index,
92 };
93 use big_s::S;
94 use meilisearch_test_macro::meilisearch_test;
95 use serde::{Deserialize, Serialize};
96 use std::time::Duration;
97
98 #[derive(Debug, Serialize, Deserialize, PartialEq)]
99 struct Document {
100 id: usize,
101 value: String,
102 kind: String,
103 }
104
105 #[test]
106 fn test_deserialize_task_info() {
107 let datetime = OffsetDateTime::parse(
108 "2022-02-03T13:02:38.369634Z",
109 &time::format_description::well_known::Rfc3339,
110 )
111 .unwrap();
112
113 let task_info: TaskInfo = serde_json::from_str(
114 r#"
115{
116 "enqueuedAt": "2022-02-03T13:02:38.369634Z",
117 "indexUid": "meili",
118 "status": "enqueued",
119 "type": "documentAdditionOrUpdate",
120 "taskUid": 12
121}"#,
122 )
123 .unwrap();
124
125 assert!(matches!(
126 task_info,
127 TaskInfo {
128 enqueued_at,
129 index_uid: Some(index_uid),
130 task_uid: 12,
131 update_type: TaskType::DocumentAdditionOrUpdate { details: None },
132 status,
133 }
134 if enqueued_at == datetime && index_uid == "meili" && status == "enqueued"));
135 }
136
137 #[meilisearch_test]
138 async fn test_wait_for_task_with_args(client: Client, movies: Index) -> Result<(), Error> {
139 let task_info = movies
140 .add_documents(
141 &[
142 Document {
143 id: 0,
144 kind: "title".into(),
145 value: S("The Social Network"),
146 },
147 Document {
148 id: 1,
149 kind: "title".into(),
150 value: S("Harry Potter and the Sorcerer's Stone"),
151 },
152 ],
153 None,
154 )
155 .await?;
156
157 let task = client
158 .get_task(task_info)
159 .await?
160 .wait_for_completion(
161 &client,
162 Some(Duration::from_millis(1)),
163 Some(Duration::from_millis(6000)),
164 )
165 .await?;
166
167 assert!(matches!(task, Task::Succeeded { .. }));
168 Ok(())
169 }
170
171 #[meilisearch_test]
172 async fn test_failing_task(client: Client, index: Index) -> Result<(), Error> {
173 let task_info = client.create_index(index.uid, None).await.unwrap();
174 let task = client.wait_for_task(task_info, None, None).await?;
175
176 let error = task.unwrap_failure();
177 assert_eq!(error.error_code, ErrorCode::IndexAlreadyExists);
178 assert_eq!(error.error_type, ErrorType::InvalidRequest);
179 Ok(())
180 }
181}