1use json::{object, JsonValue};
2use serde::{Deserialize, Serialize};
3use std::collections::BTreeMap;
4use std::fs;
5use std::path::PathBuf;
6
7#[derive(Clone, Debug, Deserialize, Serialize)]
8pub struct Config {
9 pub default: String,
10 pub connections: BTreeMap<String, Connection>,
11}
12
13impl Default for Config {
14 fn default() -> Self {
15 Self::new()
16 }
17}
18
19impl Config {
20 pub fn create(config_file: PathBuf, pkg_name: bool) -> Config {
24 #[derive(Clone, Debug, Deserialize, Serialize)]
25 pub struct ConfigNew {
26 pub br_cache: Config,
27 }
28 impl ConfigNew {
29 pub fn new() -> ConfigNew {
30 let mut connections = BTreeMap::new();
31 connections.insert("my_name".to_string(), Connection::default());
32 Self {
33 br_cache: Config {
34 default: "my_name".to_string(),
35 connections,
36 },
37 }
38 }
39 }
40 match fs::read_to_string(config_file.clone()) {
41 Ok(e) => {
42 if pkg_name {
43 let data = ConfigNew::new();
44 toml::from_str::<ConfigNew>(&e)
45 .unwrap_or_else(|_| {
46 let toml = toml::to_string(&data).unwrap();
47 let toml = format!("{e}\r\n{toml}");
48 let _ = fs::write(config_file.to_str().unwrap(), toml);
49 data
50 })
51 .br_cache
52 } else {
53 Config::new()
54 }
55 }
56 Err(_) => {
57 if pkg_name {
58 let data = ConfigNew::new();
59 fs::create_dir_all(config_file.parent().unwrap()).unwrap();
60 let toml = toml::to_string(&data).unwrap();
61 let _ = fs::write(config_file.to_str().unwrap(), toml);
62 data.br_cache
63 } else {
64 let data = Config::new();
65 fs::create_dir_all(config_file.parent().unwrap()).unwrap();
66 let toml = toml::to_string(&data).unwrap();
67 let _ = fs::write(config_file.to_str().unwrap(), toml);
68 data
69 }
70 }
71 }
72 }
73 pub fn new() -> Config {
74 let mut connections = BTreeMap::new();
75 connections.insert("my_name".to_string(), Connection::default());
76 Self {
77 default: "my_name".to_string(),
78 connections,
79 }
80 }
81}
82
83#[derive(Clone, Debug, Serialize, Deserialize)]
84pub struct Connection {
85 pub mode: CacheMode,
86 pub hostname: String,
87 pub hostport: String,
88 pub userpass: String,
89 #[serde(default)]
90 pub kafka: Option<KafkaConnection>,
91}
92impl Default for Connection {
93 fn default() -> Self {
94 Self {
95 mode: CacheMode::Redis,
96 hostname: "127.0.0.1".to_string(),
97 hostport: "6379".to_string(),
98 userpass: "".to_string(),
99 kafka: None,
100 }
101 }
102}
103impl Connection {
104 pub fn from(data: JsonValue) -> Connection {
105 let kafka = if data["kafka"].is_object() {
106 Some(KafkaConnection::from(data["kafka"].clone()))
107 } else {
108 None
109 };
110 Self {
111 mode: CacheMode::from(data["mode"].as_str().unwrap_or("")),
112 hostname: data["hostname"].to_string(),
113 hostport: data["hostport"].to_string(),
114 userpass: data["userpass"].to_string(),
115 kafka,
116 }
117 }
118 pub fn json(&mut self) -> JsonValue {
119 let mut data = object! {};
120 data["mode"] = self.mode.str().into();
121 data["hostname"] = self.hostname.clone().into();
122 data["hostport"] = self.hostport.clone().into();
123 data["userpass"] = self.userpass.clone().into();
124 if let Some(ref kafka) = self.kafka {
125 data["kafka"] = kafka.json();
126 }
127 data
128 }
129}
130
131#[derive(Clone, Debug, Serialize, Deserialize)]
132pub enum CacheMode {
133 Redis,
134 Kafka,
135 None,
136}
137
138impl CacheMode {
139 pub fn str(&self) -> &'static str {
140 match self {
141 CacheMode::Redis => "redis",
142 CacheMode::Kafka => "kafka",
143 CacheMode::None => "",
144 }
145 }
146 pub fn from(name: &str) -> Self {
147 match name {
148 "redis" => CacheMode::Redis,
149 "kafka" => CacheMode::Kafka,
150 _ => CacheMode::Redis,
151 }
152 }
153}
154
155#[derive(Clone, Debug, Serialize, Deserialize)]
156pub struct KafkaConnection {
157 pub brokers: Vec<String>,
158 pub fetch_max: i32,
159 pub retry_max: i32,
160}
161
162impl Default for KafkaConnection {
163 fn default() -> Self {
164 Self {
165 brokers: vec!["127.0.0.1:9092".to_string()],
166 fetch_max: 1048576,
167 retry_max: 10485760,
168 }
169 }
170}
171
172impl KafkaConnection {
173 pub fn from(data: JsonValue) -> Self {
174 let brokers = data["brokers"]
175 .members()
176 .map(|x| x.as_str().unwrap_or("").to_string())
177 .filter(|x| !x.is_empty())
178 .collect();
179 Self {
180 brokers,
181 fetch_max: data["fetch_max"].as_i32().unwrap_or(1048576),
182 retry_max: data["retry_max"].as_i32().unwrap_or(10485760),
183 }
184 }
185
186 pub fn json(&self) -> JsonValue {
187 object! {
188 brokers: self.brokers.clone(),
189 fetch_max: self.fetch_max,
190 retry_max: self.retry_max
191 }
192 }
193}