toe_beans/v4/server/
config.rs1use crate::v4::{LeaseConfig, MessageOptions, SocketConfig};
2use log::{info, warn};
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::fs::{OpenOptions, read_to_string};
6use std::io::Write;
7use std::net::Ipv4Addr;
8use std::os::unix::fs::OpenOptionsExt;
9use std::path::PathBuf;
10use toml;
11
12#[derive(Serialize, Deserialize, Debug)]
16pub struct InnerServerConfig {
17 pub rapid_commit: bool,
19 pub server_address: Option<Ipv4Addr>,
25 pub parameters: HashMap<u8, MessageOptions>,
27}
28
29impl Default for InnerServerConfig {
30 fn default() -> Self {
31 Self {
32 rapid_commit: true,
33 server_address: None,
34 parameters: HashMap::with_capacity(u8::MAX as usize),
35 }
36 }
37}
38
39#[derive(Serialize, Deserialize, Debug)]
43pub struct ServerConfig {
44 #[serde(skip)]
46 pub path: PathBuf,
47 pub server: InnerServerConfig,
49 pub socket_config: SocketConfig,
51 pub lease_config: LeaseConfig,
53}
54
55impl Default for ServerConfig {
56 fn default() -> Self {
57 Self {
58 path: PathBuf::new(), server: InnerServerConfig::default(),
60 socket_config: SocketConfig::default_server(),
61 lease_config: LeaseConfig::default(),
62 }
63 }
64}
65
66impl ServerConfig {
67 pub const FILE_NAME: &'static str = "toe-beans.toml";
69
70 pub fn read(from_where: PathBuf) -> Self {
73 let read_result = read_to_string(from_where.join(Self::FILE_NAME));
74 if let Ok(config_string) = read_result {
75 let toml_result = toml::from_str(&config_string);
76 match toml_result {
77 Ok(config) => {
78 return Self {
79 path: from_where, ..config
81 };
82 }
83 Err(error) => {
84 warn!("{error}");
85 warn!(
86 "Warning: invalid {}. Using default values.",
87 Self::FILE_NAME
88 );
89 }
90 }
91 } else {
92 warn!(
93 "Warning: can't read {}. Using default values.",
94 Self::FILE_NAME
95 );
96 }
97
98 Self {
99 path: from_where,
100 ..ServerConfig::default()
101 }
102 }
103
104 pub fn write(&self) {
106 info!("Writing {}", Self::FILE_NAME);
107
108 let config_content = toml::to_string_pretty(self).expect("Failed to generate toml data");
109 let mode = 0o600;
110
111 let mut file = OpenOptions::new()
112 .read(false)
113 .write(true)
114 .create(true)
115 .truncate(true)
116 .mode(mode) .open(self.path.join(Self::FILE_NAME))
118 .unwrap_or_else(|_| panic!("Failed to open config {} for writing", Self::FILE_NAME));
119
120 file.write_all(config_content.as_bytes())
121 .unwrap_or_else(|_| panic!("Failed to write config to {}", Self::FILE_NAME));
122 }
123}