genja_core/settings/
root.rs1use super::{CoreConfig, InventoryConfig, LoggingConfig, RunnerConfig, SSHConfig};
2use crate::ConfigLoadError;
3use config::{Config as ConfigBuilder, File, FileFormat};
4use serde::{Deserialize, Serialize};
5
6#[derive(Deserialize, Serialize, Clone, Debug, Default)]
10#[serde(default)]
11pub struct Settings {
12 core: CoreConfig,
13 inventory: InventoryConfig,
14 ssh: SSHConfig,
15 runner: RunnerConfig,
16 logging: LoggingConfig,
17}
18
19impl Settings {
20 pub fn from_file(file_path: &str) -> Result<Self, ConfigLoadError> {
25 let format = if file_path.ends_with(".json") {
26 FileFormat::Json
27 } else if file_path.ends_with(".yaml") || file_path.ends_with(".yml") {
28 FileFormat::Yaml
29 } else {
30 return Err(ConfigLoadError::UnsupportedFormat {
31 path: file_path.to_string(),
32 });
33 };
34 let config = ConfigBuilder::builder()
35 .add_source(File::new(file_path, format).required(true))
36 .build()
37 .map_err(|err| ConfigLoadError::Read {
38 path: file_path.to_string(),
39 message: err.to_string(),
40 })?;
41 let parsed_config: Settings =
42 config
43 .try_deserialize()
44 .map_err(|err| ConfigLoadError::Deserialize {
45 path: file_path.to_string(),
46 message: err.to_string(),
47 })?;
48
49 parsed_config
50 .ssh
51 .validate()
52 .map_err(ConfigLoadError::SshConfig)?;
53 Ok(parsed_config)
54 }
55
56 pub fn core(&self) -> &CoreConfig {
57 &self.core
58 }
59
60 pub fn inventory(&self) -> &InventoryConfig {
61 &self.inventory
62 }
63
64 pub fn ssh(&self) -> &SSHConfig {
65 &self.ssh
66 }
67
68 pub fn runner(&self) -> &RunnerConfig {
69 &self.runner
70 }
71
72 pub fn logging(&self) -> &LoggingConfig {
73 &self.logging
74 }
75}
76
77impl Settings {
78 pub fn builder() -> SettingsBuilder {
79 SettingsBuilder::default()
80 }
81}
82
83#[derive(Default)]
85pub struct SettingsBuilder {
86 core: Option<CoreConfig>,
87 inventory: Option<InventoryConfig>,
88 ssh: Option<SSHConfig>,
89 runner: Option<RunnerConfig>,
90 logging: Option<LoggingConfig>,
91}
92
93impl SettingsBuilder {
94 pub fn core(mut self, core: CoreConfig) -> Self {
95 self.core = Some(core);
96 self
97 }
98
99 pub fn inventory(mut self, inventory: InventoryConfig) -> Self {
100 self.inventory = Some(inventory);
101 self
102 }
103
104 pub fn ssh(mut self, ssh: SSHConfig) -> Self {
105 self.ssh = Some(ssh);
106 self
107 }
108
109 pub fn runner(mut self, runner: RunnerConfig) -> Self {
110 self.runner = Some(runner);
111 self
112 }
113
114 pub fn logging(mut self, logging: LoggingConfig) -> Self {
115 self.logging = Some(logging);
116 self
117 }
118
119 pub fn build(self) -> Settings {
120 Settings {
121 core: self.core.unwrap_or_default(),
122 inventory: self.inventory.unwrap_or_default(),
123 ssh: self.ssh.unwrap_or_default(),
124 runner: self.runner.unwrap_or_default(),
125 logging: self.logging.unwrap_or_default(),
126 }
127 }
128}