tasks_handler locks a Mutex with IndexMap to iterate over all Record values to render them as a part of the Tasks struct:
fn tasks_handler(req: HttpRequest<State>) -> impl Future<Item = HttpResponse, Error = WebError> {
let tasks: Vec<_> = req
.state()
.tasks
.lock()
.unwrap()
.values()
.cloned()
.collect();
let tmpl = Tasks { tasks };
future::ok(HttpResponse::Ok().body(tmpl.render().unwrap()))
}
If you remember, we added the askama crate to render templates. Create a templates folder in the root of project and add a tasks.html file with some HTML code that contains at least the following rendering table:
<table>
<thead>
<tr>
<th>Task ID</th>
<th>Timestamp</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for task in tasks %}
<tr>
<td>{{ task.task_id }}</td>
<td>{{ task.timestamp }}</td>
<td>{{ task.status }}</td>
</tr>
{% endfor %}
</tbody>
</table>
This is a part of the full template that you can find in the examples folder for this book, but the preceding code contains code for rendering a table with all the tasks extracted from the Tasks struct, which is implemented as follows:
#[derive(Template)]
#[template(path = "tasks.html")]
struct Tasks {
tasks: Vec<Record>,
}
Derive the Template type for this struct and attach the template with the template attribute. askama will embed the template into your code. That's very convenient.