Skip to main content

ombrac_server/config/
json.rs

1use std::error::Error;
2
3use serde::{Deserialize, Serialize};
4
5#[cfg(feature = "tracing")]
6use crate::config::LoggingConfig;
7use crate::config::{ConnectionConfig, TransportConfig};
8
9/// JSON configuration file structure
10#[derive(Deserialize, Serialize, Debug, Default)]
11#[serde(rename_all = "snake_case")]
12pub struct JsonConfig {
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub secret: Option<String>,
15
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub listen: Option<std::net::SocketAddr>,
18
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub transport: Option<TransportConfig>,
21
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub connection: Option<ConnectionConfig>,
24
25    #[cfg(feature = "tracing")]
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub logging: Option<LoggingConfig>,
28}
29
30impl JsonConfig {
31    /// Load configuration from a JSON string
32    ///
33    /// # Arguments
34    ///
35    /// * `json_str` - A JSON string containing the configuration
36    ///
37    /// # Returns
38    ///
39    /// A `JsonConfig` instance, or an error if parsing fails
40    pub fn from_json_str(json_str: &str) -> Result<Self, Box<dyn Error>> {
41        let config: JsonConfig = serde_json::from_str(json_str)?;
42        Ok(config)
43    }
44
45    /// Load configuration from a JSON file
46    ///
47    /// # Arguments
48    ///
49    /// * `config_path` - Path to the JSON configuration file
50    ///
51    /// # Returns
52    ///
53    /// A `JsonConfig` instance, or an error if the file doesn't exist or parsing fails
54    pub fn from_file(config_path: &std::path::Path) -> Result<Self, Box<dyn Error>> {
55        if !config_path.exists() {
56            return Err(format!("Configuration file not found: {}", config_path.display()).into());
57        }
58
59        let content = std::fs::read_to_string(config_path)?;
60        Self::from_json_str(&content)
61    }
62}