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 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}