freedom_api/api/post/
overrides.rs

1use std::collections::HashMap;
2
3use serde::Serialize;
4
5use crate::{api::Api, error::Error};
6
7use super::{Post, UrlResult};
8
9#[derive(Debug, Clone, PartialEq, Serialize)]
10#[serde(rename_all = "camelCase")]
11struct OverrideInner {
12    name: String,
13    satellite: String,
14    configuration: String,
15    properties: HashMap<String, String>,
16}
17
18#[derive(Debug, Clone, PartialEq)]
19pub struct Override {
20    name: String,
21    satellite: UrlResult,
22    configuration: UrlResult,
23    properties: HashMap<String, String>,
24}
25
26pub struct OverrideBuilder<'a, C, S> {
27    pub(crate) client: &'a C,
28    state: S,
29}
30
31pub fn new<C>(client: &C) -> OverrideBuilder<'_, C, NoName> {
32    OverrideBuilder {
33        client,
34        state: NoName,
35    }
36}
37
38pub struct NoName;
39
40impl<'a, C> OverrideBuilder<'a, C, NoName> {
41    pub fn name(self, name: impl Into<String>) -> OverrideBuilder<'a, C, NoSatellite> {
42        OverrideBuilder {
43            client: self.client,
44            state: NoSatellite { name: name.into() },
45        }
46    }
47}
48
49pub struct NoSatellite {
50    name: String,
51}
52
53impl<'a, C> OverrideBuilder<'a, C, NoSatellite>
54where
55    C: Api,
56{
57    pub fn satellite_id(self, id: impl Into<i32>) -> OverrideBuilder<'a, C, NoConfig> {
58        let satellite = self.client.path_to_url(format!("satellites/{}", id.into()));
59
60        self.satellite_result(UrlResult::Unchecked(satellite))
61    }
62}
63
64impl<'a, C> OverrideBuilder<'a, C, NoSatellite> {
65    fn satellite_result(self, url: UrlResult) -> OverrideBuilder<'a, C, NoConfig> {
66        OverrideBuilder {
67            client: self.client,
68            state: NoConfig {
69                name: self.state.name,
70                satellite: url,
71            },
72        }
73    }
74
75    pub fn satellite_url(self, url: impl Into<String>) -> OverrideBuilder<'a, C, NoConfig> {
76        self.satellite_result(UrlResult::Checked(url.into()))
77    }
78}
79
80pub struct NoConfig {
81    name: String,
82    satellite: UrlResult,
83}
84
85impl<'a, C> OverrideBuilder<'a, C, NoConfig>
86where
87    C: Api,
88{
89    pub fn satellite_configuration_id(
90        self,
91        id: impl Into<i32>,
92    ) -> OverrideBuilder<'a, C, Override> {
93        let url = self.client.path_to_url(format!("satellites/{}", id.into()));
94        self.satellite_configuration_result(UrlResult::Unchecked(url))
95    }
96}
97
98impl<'a, C> OverrideBuilder<'a, C, NoConfig> {
99    fn satellite_configuration_result(self, url: UrlResult) -> OverrideBuilder<'a, C, Override> {
100        let state = Override {
101            name: self.state.name,
102            satellite: self.state.satellite,
103            configuration: url,
104            properties: HashMap::new(),
105        };
106
107        OverrideBuilder {
108            client: self.client,
109            state,
110        }
111    }
112
113    pub fn satellite_configuration_url(
114        self,
115        url: impl Into<String>,
116    ) -> OverrideBuilder<'a, C, Override> {
117        self.satellite_configuration_result(UrlResult::Checked(url.into()))
118    }
119}
120
121impl<C> OverrideBuilder<'_, C, Override> {
122    /// Can be invoked multiple times to add properties to the override
123    pub fn with_property(mut self, key: impl Into<String>, value: impl ToString) -> Self {
124        self.state.properties.insert(key.into(), value.to_string());
125        self
126    }
127}
128
129impl<C> Post for OverrideBuilder<'_, C, Override>
130where
131    C: Api,
132{
133    type Response = freedom_models::task_override::Override;
134
135    async fn send(self) -> Result<Self::Response, Error> {
136        let client = self.client;
137
138        let url = client.path_to_url("overrides")?;
139
140        let configuration = self.state.configuration.try_convert()?;
141        let satellite = self.state.satellite.try_convert()?;
142
143        let dto = OverrideInner {
144            name: self.state.name,
145            satellite,
146            configuration,
147            properties: self.state.properties,
148        };
149
150        client.post_json_map(url, dto).await
151    }
152}