1use freedom_models::{
2 band::{BandType, IoConfiguration, IoHardware},
3 task::Polarization,
4};
5use serde::Serialize;
6
7use crate::{api::Api, error::Error};
8
9use super::Post;
10
11#[derive(Debug, Clone, PartialEq, Serialize)]
12#[serde(rename_all = "camelCase")]
13pub struct BandDetails {
14 name: String,
15 #[serde(rename(serialize = "type"))]
16 typ: BandType,
17 frequency_mghz: f64,
18 default_band_width_mghz: f64,
19 modulation: Option<String>,
20 eirp: Option<f64>,
21 gain: Option<f64>,
22 io_configuration: IoConfiguration,
23 polarization: Option<Polarization>,
24 manual_transmit_control: bool,
25}
26
27pub struct BandDetailsBuilder<'a, C, S> {
28 pub(crate) client: &'a C,
29 state: S,
30}
31
32pub struct NoName;
33
34pub fn new<C>(client: &C) -> BandDetailsBuilder<'_, C, NoName> {
35 BandDetailsBuilder {
36 client,
37 state: NoName,
38 }
39}
40
41impl<'a, C> BandDetailsBuilder<'a, C, NoName> {
42 pub fn name(self, name: impl Into<String>) -> BandDetailsBuilder<'a, C, NoBandType> {
43 BandDetailsBuilder {
44 client: self.client,
45 state: NoBandType { name: name.into() },
46 }
47 }
48}
49
50pub struct NoBandType {
51 name: String,
52}
53
54impl<'a, C> BandDetailsBuilder<'a, C, NoBandType> {
55 pub fn band_type(self, band_type: BandType) -> BandDetailsBuilder<'a, C, NoFrequency> {
56 BandDetailsBuilder {
57 client: self.client,
58 state: NoFrequency {
59 name: self.state.name,
60 band_type,
61 },
62 }
63 }
64}
65
66pub struct NoFrequency {
67 name: String,
68 band_type: BandType,
69}
70
71impl<'a, C> BandDetailsBuilder<'a, C, NoFrequency> {
72 pub fn frequency(self, frequency: impl Into<f64>) -> BandDetailsBuilder<'a, C, NoBandWidth> {
73 BandDetailsBuilder {
74 client: self.client,
75 state: NoBandWidth {
76 name: self.state.name,
77 band_type: self.state.band_type,
78 frequency_mghz: frequency.into(),
79 },
80 }
81 }
82}
83
84pub struct NoBandWidth {
85 name: String,
86 band_type: BandType,
87 frequency_mghz: f64,
88}
89
90impl<'a, C> BandDetailsBuilder<'a, C, NoBandWidth> {
91 pub fn default_band_width(
92 self,
93 bandwidth_mghz: impl Into<f64>,
94 ) -> BandDetailsBuilder<'a, C, NoIoConfig> {
95 BandDetailsBuilder {
96 client: self.client,
97 state: NoIoConfig {
98 name: self.state.name,
99 band_type: self.state.band_type,
100 frequency_mghz: self.state.frequency_mghz,
101 default_band_width_mghz: bandwidth_mghz.into(),
102 },
103 }
104 }
105}
106
107pub struct NoIoConfig {
108 name: String,
109 band_type: BandType,
110 frequency_mghz: f64,
111 default_band_width_mghz: f64,
112}
113
114impl<'a, C> BandDetailsBuilder<'a, C, NoIoConfig> {
115 pub fn io_hardware(self, hardware: IoHardware) -> BandDetailsBuilder<'a, C, BandDetails> {
116 let state = BandDetails {
117 name: self.state.name,
118 typ: self.state.band_type,
119 frequency_mghz: self.state.frequency_mghz,
120 default_band_width_mghz: self.state.default_band_width_mghz,
121 io_configuration: IoConfiguration {
122 start_hex_pattern: None,
123 end_hex_pattern: None,
124 strip_pattern: false,
125 io_hardware: Some(hardware),
126 },
127 modulation: None,
128 eirp: None,
129 gain: None,
130 polarization: None,
131 manual_transmit_control: false,
132 };
133
134 BandDetailsBuilder {
135 client: self.client,
136 state,
137 }
138 }
139}
140
141impl<C> BandDetailsBuilder<'_, C, BandDetails> {
142 pub fn polarization(mut self, polarization: Polarization) -> Self {
143 self.state.polarization = Some(polarization);
144 self
145 }
146
147 pub fn modulation(mut self, modulation: impl Into<String>) -> Self {
148 self.state.modulation = Some(modulation.into());
149 self
150 }
151
152 pub fn effective_isotropic_radiative_power(mut self, eirp: impl Into<f64>) -> Self {
153 self.state.eirp = Some(eirp.into());
154 self
155 }
156
157 pub fn gain(mut self, gain: impl Into<f64>) -> Self {
158 self.state.gain = Some(gain.into());
159 self
160 }
161
162 pub fn manual_transmit_control(mut self, control: bool) -> Self {
163 self.state.manual_transmit_control = control;
164 self
165 }
166}
167
168impl<C> Post for BandDetailsBuilder<'_, C, BandDetails>
169where
170 C: Api,
171{
172 type Response = freedom_models::band::Band;
173
174 async fn send(self) -> Result<Self::Response, Error> {
175 let client = self.client;
176
177 let url = client.path_to_url("satellite_bands")?;
178 client.post_json_map(url, self.state).await
179 }
180}