1use json::JsonValue;
2use std::time::Duration;
3
4#[derive(Clone, Debug)]
5pub struct Config {
6 pub debug: bool,
8 pub username: String,
10 pub userpass: String,
12 pub database: String,
14 pub hostname: String,
16 pub hostport: i32,
18 pub charset: String,
20 pub pool_max: u32,
22}
23
24#[derive(Clone, Debug)]
26pub struct PoolConstraints {
27 pub min: usize,
29 pub max: usize,
31}
32
33impl PoolConstraints {
34 pub fn new(min: usize, max: usize) -> Result<Self, String> {
43 if min > 1000 {
44 return Err("最小连接数不能超过 1000".into());
45 }
46 if max > 1000 {
47 return Err("最大连接数不能超过 1000".into());
48 }
49 if max < min {
50 return Err("最大连接数必须大于等于最小连接数".into());
51 }
52 if max == 0 {
53 return Err("最大连接数必须大于 0".into());
54 }
55 Ok(Self { min, max })
56 }
57}
58
59impl Default for PoolConstraints {
60 fn default() -> Self {
61 Self { min: 0, max: 10 }
62 }
63}
64
65#[derive(Clone, Debug)]
67pub struct PoolOpts {
68 pub constraints: PoolConstraints,
70 pub reset_connection: bool,
72 pub connect_timeout: Duration,
74 pub read_timeout: Duration,
76 pub write_timeout: Duration,
78 pub tcp_keepalive: Duration,
80}
81
82impl Default for PoolOpts {
83 fn default() -> Self {
84 Self {
85 constraints: PoolConstraints::default(),
86 reset_connection: true,
87 connect_timeout: Duration::from_secs(5),
88 read_timeout: Duration::from_secs(15),
89 write_timeout: Duration::from_secs(20),
90 tcp_keepalive: Duration::from_secs(5),
91 }
92 }
93}
94
95impl PoolOpts {
96
97 pub fn with_constraints(mut self, constraints: PoolConstraints) -> Self {
99 self.constraints = constraints;
100 self
101 }
102
103 pub fn with_reset_connection(mut self, reset: bool) -> Self {
105 self.reset_connection = reset;
106 self
107 }
108
109 pub fn with_connect_timeout(mut self, timeout: Duration) -> Self {
111 self.connect_timeout = timeout;
112 self
113 }
114
115 pub fn with_read_timeout(mut self, timeout: Duration) -> Self {
117 self.read_timeout = timeout;
118 self
119 }
120
121 pub fn with_write_timeout(mut self, timeout: Duration) -> Self {
123 self.write_timeout = timeout;
124 self
125 }
126
127 pub fn with_tcp_keepalive(mut self, keepalive: Duration) -> Self {
129 self.tcp_keepalive = keepalive;
130 self
131 }
132}
133
134impl Config {
135 pub fn new(config: &JsonValue) -> Result<Config, String> {
136 let hostname = config["hostname"].as_str()
137 .ok_or("hostname 配置缺失")?
138 .to_string();
139
140 if hostname.is_empty() {
141 return Err("hostname 不能为空".into());
142 }
143
144 let hostport = config["hostport"].as_i32()
145 .filter(|&p| p > 0 && p <= 65535)
146 .ok_or("hostport 必须是 1-65535 之间的整数")?;
147
148 let username = config["username"].as_str()
149 .unwrap_or("postgres")
150 .to_string();
151
152 if username.is_empty() {
153 return Err("username 不能为空".into());
154 }
155
156 let database = config["database"].as_str()
157 .unwrap_or("postgres")
158 .to_string();
159
160 if database.is_empty() {
161 return Err("database 不能为空".into());
162 }
163
164 Ok(Self {
165 debug: config["debug"].as_bool().unwrap_or(false),
166 username,
167 userpass: config["userpass"].as_str().unwrap_or("111111").to_string(),
168 database,
169 hostname,
170 hostport,
171 charset: config["charset"].as_str().unwrap_or("utf8mb4").to_string(),
172 pool_max: config["pool_max"].as_u32()
173 .filter(|&p| p > 0 && p <= 1000)
174 .unwrap_or(5),
175 })
176 }
177
178 pub fn url(&self) -> String {
179 format!("{}:{}", self.hostname, self.hostport)
180 }
181}