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

            
4
use std::fmt;
5

            
6
use reqwest::Client;
7
use serde::{Deserialize, Serialize};
8
use url::Url;
9

            
10
use crate::ddi::client::Error;
11
use crate::ddi::feedback::Feedback;
12

            
13
#[derive(Debug, Deserialize)]
14
pub struct Link {
15
    href: String,
16
}
17

            
18
impl fmt::Display for Link {
19
100
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20
100
        write!(f, "{}", self.href)
21
100
    }
22
}
23

            
24
#[derive(Debug, Serialize)]
25
#[serde(rename_all = "lowercase")]
26
/// Sent by the target to the server informing it about the execution state of a pending request,
27
/// see the [DDI API reference](https://www.eclipse.org/hawkbit/apis/ddi_api/) for details.
28
pub enum Execution {
29
    /// Target completes the action either with `Finished::Success` or `Finished::Failure` as result.
30
    Closed,
31
    /// This can be used by the target to inform that it is working on the action.
32
    Proceeding,
33
    /// This is send by the target as confirmation of a cancellation request by the update server.
34
    Canceled,
35
    /// This can be used by the target to inform that it scheduled on the action.
36
    Scheduled,
37
    /// This is send by the target in case an update of a cancellation is rejected, i.e. cannot be fulfilled at this point in time.
38
    Rejected,
39
    /// This can be used by the target to inform that it continued to work on the action.
40
    Resumed,
41
    /// This can be used to inform the server that the target finished downloading the artifact.
42
    Downloaded,
43
    /// This can be used to inform the server that the target is downloading the artifact.
44
    Download,
45
}
46

            
47
#[derive(Debug, Serialize)]
48
#[serde(rename_all = "lowercase")]
49
/// Status of a pending operation
50
pub enum Finished {
51
    /// Operation suceeded
52
    Success,
53
    /// Operation failed
54
    Failure,
55
    /// Operation is still in-progress
56
    None,
57
}
58

            
59
6
pub(crate) async fn send_feedback_internal<T: Serialize>(
60
6
    client: &Client,
61
6
    url: &str,
62
6
    id: &str,
63
6
    execution: Execution,
64
6
    finished: Finished,
65
6
    progress: Option<T>,
66
6
    details: Vec<&str>,
67
6
) -> Result<(), Error> {
68
6
    let mut url: Url = url.parse()?;
69
    {
70
6
        let mut paths = url
71
6
            .path_segments_mut()
72
6
            .map_err(|_| url::ParseError::SetHostOnCannotBeABaseUrl)?;
73
6
        paths.push("feedback");
74
    }
75
6
    url.set_query(None);
76

            
77
6
    let details = details.iter().map(|m| m.to_string()).collect();
78
6
    let feedback = Feedback::new(id, execution, finished, progress, details);
79

            
80
6
    let reply = client.post(url.to_string()).json(&feedback).send().await?;
81
6
    reply.error_for_status()?;
82

            
83
6
    Ok(())
84
6
}