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