1use crate::Error;
2use serde::{Deserialize, Serialize};
3use serde_ini::{Serializer, Writer};
4use std::io::{Read, Write};
5
6#[derive(Serialize, Deserialize, Debug, Clone)]
7pub struct Properties {
9 #[serde(skip_serializing_if = "Option::is_none")]
11 core: Option<CoreProperties>,
12
13 #[serde(skip_serializing_if = "Option::is_none")]
15 compute: Option<ComputeProperties>,
16}
17
18impl Properties {
19 pub fn from_reader<R: Read>(reader: R) -> Result<Self, Error> {
21 let properties = serde_ini::de::from_read(reader)?;
22 Ok(properties)
23 }
24
25 pub fn to_writer<W: Write>(&self, writer: W) -> Result<(), Error> {
27 let mut ser = Serializer::new(Writer::new(writer, serde_ini::LineEnding::Linefeed));
28 self.serialize(&mut ser)?;
29
30 Ok(())
31 }
32}
33
34#[derive(Serialize, Deserialize, Debug, Clone, Default)]
35struct CoreProperties {
37 #[serde(skip_serializing_if = "Option::is_none")]
39 project: Option<String>,
40
41 #[serde(skip_serializing_if = "Option::is_none")]
43 account: Option<String>,
44}
45
46#[derive(Serialize, Deserialize, Debug, Clone, Default)]
47struct ComputeProperties {
49 #[serde(skip_serializing_if = "Option::is_none")]
51 zone: Option<String>,
52
53 #[serde(skip_serializing_if = "Option::is_none")]
55 region: Option<String>,
56}
57
58#[derive(Debug, Default)]
59pub struct PropertiesBuilder {
61 project: Option<String>,
63
64 account: Option<String>,
66
67 zone: Option<String>,
69
70 region: Option<String>,
72}
73
74impl PropertiesBuilder {
75 pub fn build(&self) -> Properties {
77 let core = if self.project.is_some() || self.account.is_some() {
78 Some(CoreProperties {
79 project: self.project.clone(),
80 account: self.account.clone(),
81 })
82 } else {
83 None
84 };
85
86 let compute = if self.zone.is_some() || self.region.is_some() {
87 Some(ComputeProperties {
88 zone: self.zone.clone(),
89 region: self.region.clone(),
90 })
91 } else {
92 None
93 };
94
95 Properties { core, compute }
96 }
97
98 pub fn project(&mut self, project: &str) -> &mut Self {
100 self.project = Some(project.to_owned());
101 self
102 }
103
104 pub fn account(&mut self, account: &str) -> &mut Self {
106 self.account = Some(account.to_owned());
107 self
108 }
109
110 pub fn zone(&mut self, zone: &str) -> &mut Self {
112 self.zone = Some(zone.to_owned());
113 self
114 }
115
116 pub fn region(&mut self, region: &str) -> &mut Self {
118 self.region = Some(region.to_owned());
119 self
120 }
121}