1
// Copyright 2021, Collabora Ltd.
2
// SPDX-License-Identifier: MIT OR Apache-2.0
3

            
4
// Cancelled operation
5

            
6
use reqwest::Client;
7
use serde::Deserialize;
8

            
9
use crate::ddi::client::Error;
10
use crate::ddi::common::{send_feedback_internal, Execution, Finished};
11

            
12
/// A request from the server to cancel an update.
13
///
14
/// Call [`CancelAction::id()`] to retrieve the ID of the action to cancel.
15
///
16
/// Cancel actions need to be closed by sending feedback to the server using
17
/// [`CancelAction::send_feedback`] with either
18
/// [`Finished::Success`] or [`Finished::Failure`].
19
#[derive(Debug)]
20
pub struct CancelAction {
21
    client: Client,
22
    url: String,
23
}
24

            
25
impl CancelAction {
26
4
    pub(crate) fn new(client: Client, url: String) -> Self {
27
4
        Self { client, url }
28
4
    }
29

            
30
    /// Retrieve the id of the action to cancel.
31
10
    pub async fn id(&self) -> Result<String, Error> {
32
4
        let reply = self.client.get(&self.url).send().await?;
33
4
        reply.error_for_status_ref()?;
34

            
35
4
        let reply = reply.json::<CancelReply>().await?;
36
4
        Ok(reply.cancel_action.stop_id)
37
4
    }
38

            
39
    /// Send feedback to server about this cancel action.
40
    ///
41
    /// # Arguments
42
    /// * `execution`: status of the action execution.
43
    /// * `finished`: defined status of the result. The action will be kept open on the server until the controller on the device reports either [`Finished::Success`] or [`Finished::Failure`].
44
    /// * `details`: list of details message information.
45
4
    pub async fn send_feedback(
46
4
        &self,
47
4
        execution: Execution,
48
4
        finished: Finished,
49
4
        details: Vec<&str>,
50
5
    ) -> Result<(), Error> {
51
2
        let id = self.id().await?;
52

            
53
2
        send_feedback_internal::<bool>(
54
2
            &self.client,
55
2
            &self.url,
56
2
            &id,
57
2
            execution,
58
2
            finished,
59
2
            None,
60
2
            details,
61
2
        )
62
2
        .await
63
2
    }
64
}
65

            
66
#[allow(dead_code)]
67
#[derive(Debug, Deserialize)]
68
struct CancelReply {
69
    id: String,
70
    #[serde(rename = "cancelAction")]
71
    cancel_action: CancelActionReply,
72
}
73

            
74
#[derive(Debug, Deserialize)]
75
struct CancelActionReply {
76
    #[serde(rename = "stopId")]
77
    stop_id: String,
78
}