toe_beans/v4/server/config/
mod.rs1mod lease_time;
2
3pub use lease_time::LeaseTime;
4use ipnetwork::Ipv4Network;
5use log::{info, warn};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::fs::{read_to_string, OpenOptions};
9use std::io::Write;
10use std::net::{Ipv4Addr, SocketAddrV4};
11use std::os::unix::fs::OpenOptionsExt;
12use std::path::PathBuf;
13use toml;
14use crate::v4::MessageOptions;
15
16#[derive(Serialize, Deserialize, Debug)]
20pub struct Config {
21 #[serde(skip)]
23 pub path: PathBuf,
24 pub lease_time: LeaseTime,
26 pub rapid_commit: bool,
28 pub network_cidr: Ipv4Network,
30 pub listen_address: SocketAddrV4,
32 pub interface: Option<String>,
35 pub server_address: Option<Ipv4Addr>,
41 pub parameters: HashMap<String, MessageOptions>
44}
45
46impl Default for Config {
47 fn default() -> Self {
48 Self {
49 path: PathBuf::new(), lease_time: LeaseTime::new(86_400).unwrap(), rapid_commit: true,
52 network_cidr: Ipv4Network::new(Ipv4Addr::new(10, 0, 0, 0), 16).unwrap(), listen_address: SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 8067),
54 interface: None,
55 server_address: None,
56 parameters: HashMap::with_capacity(u8::MAX as usize)
57 }
58 }
59}
60
61impl Config {
62 pub const FILE_NAME: &'static str = "toe-beans.toml";
64
65 pub fn read(from_where: PathBuf) -> Self {
68 let read_result = read_to_string(from_where.join(Self::FILE_NAME));
69 if let Ok(config_string) = read_result {
70 let toml_result = toml::from_str(&config_string);
71 match toml_result {
72 Ok(config) => {
73 return Self {
74 path: from_where, ..config
76 }
77 }
78 Err(error) => {
79 warn!("{error}");
80 warn!(
81 "Warning: invalid {}. Using default values.",
82 Self::FILE_NAME
83 );
84 }
85 }
86 } else {
87 warn!(
88 "Warning: can't read {}. Using default values.",
89 Self::FILE_NAME
90 );
91 }
92
93 Self {
94 path: from_where,
95 ..Config::default()
96 }
97 }
98
99 pub fn write(&self) {
101 info!("Writing {}", Self::FILE_NAME);
102
103 let config_content = toml::to_string_pretty(self).expect("Failed to generate toml data");
104 let mode = 0o600;
105
106 let mut file = OpenOptions::new()
107 .read(false)
108 .write(true)
109 .create(true)
110 .truncate(true)
111 .mode(mode) .open(self.path.join(Self::FILE_NAME))
113 .unwrap_or_else(|_| panic!("Failed to open config {} for writing", Self::FILE_NAME));
114
115 file.write_all(config_content.as_bytes())
116 .unwrap_or_else(|_| panic!("Failed to write config to {}", Self::FILE_NAME));
117 }
118}