postgresql_commands/
pg_config.rs1use crate::Settings;
2use crate::traits::CommandBuilder;
3use std::convert::AsRef;
4use std::ffi::{OsStr, OsString};
5use std::path::PathBuf;
6
7#[derive(Clone, Debug, Default)]
9pub struct PgConfigBuilder {
10 program_dir: Option<PathBuf>,
11 envs: Vec<(OsString, OsString)>,
12 bindir: bool,
13 docdir: bool,
14 htmldir: bool,
15 includedir: bool,
16 pkgincludedir: bool,
17 includedir_server: bool,
18 libdir: bool,
19 pkglibdir: bool,
20 localedir: bool,
21 mandir: bool,
22 sharedir: bool,
23 sysconfdir: bool,
24 pgxs: bool,
25 configure: bool,
26 cc: bool,
27 cppflags: bool,
28 cflags: bool,
29 cflags_sl: bool,
30 ldflags: bool,
31 ldflags_ex: bool,
32 ldflags_sl: bool,
33 libs: bool,
34 version: bool,
35 help: bool,
36}
37
38impl PgConfigBuilder {
39 #[must_use]
41 pub fn new() -> Self {
42 Self::default()
43 }
44
45 pub fn from(settings: &dyn Settings) -> Self {
47 Self::new().program_dir(settings.get_binary_dir())
48 }
49
50 #[must_use]
52 pub fn program_dir<P: Into<PathBuf>>(mut self, path: P) -> Self {
53 self.program_dir = Some(path.into());
54 self
55 }
56
57 #[must_use]
59 pub fn bindir(mut self) -> Self {
60 self.bindir = true;
61 self
62 }
63
64 #[must_use]
66 pub fn docdir(mut self) -> Self {
67 self.docdir = true;
68 self
69 }
70
71 #[must_use]
73 pub fn htmldir(mut self) -> Self {
74 self.htmldir = true;
75 self
76 }
77
78 #[must_use]
80 pub fn includedir(mut self) -> Self {
81 self.includedir = true;
82 self
83 }
84
85 #[must_use]
87 pub fn pkgincludedir(mut self) -> Self {
88 self.pkgincludedir = true;
89 self
90 }
91
92 #[must_use]
94 pub fn includedir_server(mut self) -> Self {
95 self.includedir_server = true;
96 self
97 }
98
99 #[must_use]
101 pub fn libdir(mut self) -> Self {
102 self.libdir = true;
103 self
104 }
105
106 #[must_use]
108 pub fn pkglibdir(mut self) -> Self {
109 self.pkglibdir = true;
110 self
111 }
112
113 #[must_use]
115 pub fn localedir(mut self) -> Self {
116 self.localedir = true;
117 self
118 }
119
120 #[must_use]
122 pub fn mandir(mut self) -> Self {
123 self.mandir = true;
124 self
125 }
126
127 #[must_use]
129 pub fn sharedir(mut self) -> Self {
130 self.sharedir = true;
131 self
132 }
133
134 #[must_use]
136 pub fn sysconfdir(mut self) -> Self {
137 self.sysconfdir = true;
138 self
139 }
140
141 #[must_use]
143 pub fn pgxs(mut self) -> Self {
144 self.pgxs = true;
145 self
146 }
147
148 #[must_use]
150 pub fn configure(mut self) -> Self {
151 self.configure = true;
152 self
153 }
154
155 #[must_use]
157 pub fn cc(mut self) -> Self {
158 self.cc = true;
159 self
160 }
161
162 #[must_use]
164 pub fn cppflags(mut self) -> Self {
165 self.cppflags = true;
166 self
167 }
168
169 #[must_use]
171 pub fn cflags(mut self) -> Self {
172 self.cflags = true;
173 self
174 }
175
176 #[must_use]
178 pub fn cflags_sl(mut self) -> Self {
179 self.cflags_sl = true;
180 self
181 }
182
183 #[must_use]
185 pub fn ldflags(mut self) -> Self {
186 self.ldflags = true;
187 self
188 }
189
190 #[must_use]
192 pub fn ldflags_ex(mut self) -> Self {
193 self.ldflags_ex = true;
194 self
195 }
196
197 #[must_use]
199 pub fn ldflags_sl(mut self) -> Self {
200 self.ldflags_sl = true;
201 self
202 }
203
204 #[must_use]
206 pub fn libs(mut self) -> Self {
207 self.libs = true;
208 self
209 }
210
211 #[must_use]
213 pub fn version(mut self) -> Self {
214 self.version = true;
215 self
216 }
217
218 #[must_use]
220 pub fn help(mut self) -> Self {
221 self.help = true;
222 self
223 }
224}
225
226impl CommandBuilder for PgConfigBuilder {
227 fn get_program(&self) -> &'static OsStr {
229 "pg_config".as_ref()
230 }
231
232 fn get_program_dir(&self) -> &Option<PathBuf> {
234 &self.program_dir
235 }
236
237 fn get_args(&self) -> Vec<OsString> {
239 let mut args: Vec<OsString> = Vec::new();
240
241 if self.bindir {
242 args.push("--bindir".into());
243 }
244
245 if self.docdir {
246 args.push("--docdir".into());
247 }
248
249 if self.htmldir {
250 args.push("--htmldir".into());
251 }
252
253 if self.includedir {
254 args.push("--includedir".into());
255 }
256
257 if self.pkgincludedir {
258 args.push("--pkgincludedir".into());
259 }
260
261 if self.includedir_server {
262 args.push("--includedir-server".into());
263 }
264
265 if self.libdir {
266 args.push("--libdir".into());
267 }
268
269 if self.pkglibdir {
270 args.push("--pkglibdir".into());
271 }
272
273 if self.localedir {
274 args.push("--localedir".into());
275 }
276
277 if self.mandir {
278 args.push("--mandir".into());
279 }
280
281 if self.sharedir {
282 args.push("--sharedir".into());
283 }
284
285 if self.sysconfdir {
286 args.push("--sysconfdir".into());
287 }
288
289 if self.pgxs {
290 args.push("--pgxs".into());
291 }
292
293 if self.configure {
294 args.push("--configure".into());
295 }
296
297 if self.cc {
298 args.push("--cc".into());
299 }
300
301 if self.cppflags {
302 args.push("--cppflags".into());
303 }
304
305 if self.cflags {
306 args.push("--cflags".into());
307 }
308
309 if self.cflags_sl {
310 args.push("--cflags_sl".into());
311 }
312
313 if self.ldflags {
314 args.push("--ldflags".into());
315 }
316
317 if self.ldflags_ex {
318 args.push("--ldflags_ex".into());
319 }
320
321 if self.ldflags_sl {
322 args.push("--ldflags_sl".into());
323 }
324
325 if self.libs {
326 args.push("--libs".into());
327 }
328
329 if self.version {
330 args.push("--version".into());
331 }
332
333 if self.help {
334 args.push("--help".into());
335 }
336
337 args
338 }
339
340 fn get_envs(&self) -> Vec<(OsString, OsString)> {
342 self.envs.clone()
343 }
344
345 fn env<S: AsRef<OsStr>>(mut self, key: S, value: S) -> Self {
347 self.envs
348 .push((key.as_ref().to_os_string(), value.as_ref().to_os_string()));
349 self
350 }
351}
352
353#[cfg(test)]
354mod tests {
355 use super::*;
356 use crate::TestSettings;
357 use crate::traits::CommandToString;
358 use test_log::test;
359
360 #[test]
361 fn test_builder_new() {
362 let command = PgConfigBuilder::new().program_dir(".").build();
363 assert_eq!(
364 PathBuf::from(".").join("pg_config"),
365 PathBuf::from(command.to_command_string().replace('"', ""))
366 );
367 }
368
369 #[test]
370 fn test_builder_from() {
371 let command = PgConfigBuilder::from(&TestSettings).build();
372 #[cfg(not(target_os = "windows"))]
373 let command_prefix = r#""./pg_config""#;
374 #[cfg(target_os = "windows")]
375 let command_prefix = r#"".\\pg_config""#;
376
377 assert_eq!(format!("{command_prefix}"), command.to_command_string());
378 }
379
380 #[test]
381 fn test_builder() {
382 let command = PgConfigBuilder::new()
383 .env("PGDATABASE", "database")
384 .bindir()
385 .docdir()
386 .htmldir()
387 .includedir()
388 .pkgincludedir()
389 .includedir_server()
390 .libdir()
391 .pkglibdir()
392 .localedir()
393 .mandir()
394 .sharedir()
395 .sysconfdir()
396 .pgxs()
397 .configure()
398 .cc()
399 .cppflags()
400 .cflags()
401 .cflags_sl()
402 .ldflags()
403 .ldflags_ex()
404 .ldflags_sl()
405 .libs()
406 .version()
407 .help()
408 .build();
409 #[cfg(not(target_os = "windows"))]
410 let command_prefix = r#"PGDATABASE="database" "#;
411 #[cfg(target_os = "windows")]
412 let command_prefix = String::new();
413
414 assert_eq!(
415 format!(
416 r#"{command_prefix}"pg_config" "--bindir" "--docdir" "--htmldir" "--includedir" "--pkgincludedir" "--includedir-server" "--libdir" "--pkglibdir" "--localedir" "--mandir" "--sharedir" "--sysconfdir" "--pgxs" "--configure" "--cc" "--cppflags" "--cflags" "--cflags_sl" "--ldflags" "--ldflags_ex" "--ldflags_sl" "--libs" "--version" "--help""#
417 ),
418 command.to_command_string()
419 );
420 }
421}