postgresql_commands/
pg_config.rs

1use crate::Settings;
2use crate::traits::CommandBuilder;
3use std::convert::AsRef;
4use std::ffi::{OsStr, OsString};
5use std::path::PathBuf;
6
7/// `pg_config` provides information about the installed version of `PostgreSQL`.
8#[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    /// Create a new [`PgConfigBuilder`]
40    #[must_use]
41    pub fn new() -> Self {
42        Self::default()
43    }
44
45    /// Create a new [`PgConfigBuilder`] from [Settings]
46    pub fn from(settings: &dyn Settings) -> Self {
47        Self::new().program_dir(settings.get_binary_dir())
48    }
49
50    /// Location of the program binary
51    #[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    /// Set the bindir
58    #[must_use]
59    pub fn bindir(mut self) -> Self {
60        self.bindir = true;
61        self
62    }
63
64    /// Set the docdir
65    #[must_use]
66    pub fn docdir(mut self) -> Self {
67        self.docdir = true;
68        self
69    }
70
71    /// Set the htmldir
72    #[must_use]
73    pub fn htmldir(mut self) -> Self {
74        self.htmldir = true;
75        self
76    }
77
78    /// Set the includedir
79    #[must_use]
80    pub fn includedir(mut self) -> Self {
81        self.includedir = true;
82        self
83    }
84
85    /// Set the pkgincludedir
86    #[must_use]
87    pub fn pkgincludedir(mut self) -> Self {
88        self.pkgincludedir = true;
89        self
90    }
91
92    /// Set the `includedir_server`
93    #[must_use]
94    pub fn includedir_server(mut self) -> Self {
95        self.includedir_server = true;
96        self
97    }
98
99    /// Set the libdir
100    #[must_use]
101    pub fn libdir(mut self) -> Self {
102        self.libdir = true;
103        self
104    }
105
106    /// Set the pkglibdir
107    #[must_use]
108    pub fn pkglibdir(mut self) -> Self {
109        self.pkglibdir = true;
110        self
111    }
112
113    /// Set the localedir
114    #[must_use]
115    pub fn localedir(mut self) -> Self {
116        self.localedir = true;
117        self
118    }
119
120    /// Set the mandir
121    #[must_use]
122    pub fn mandir(mut self) -> Self {
123        self.mandir = true;
124        self
125    }
126
127    /// Set the sharedir
128    #[must_use]
129    pub fn sharedir(mut self) -> Self {
130        self.sharedir = true;
131        self
132    }
133
134    /// Set the sysconfdir
135    #[must_use]
136    pub fn sysconfdir(mut self) -> Self {
137        self.sysconfdir = true;
138        self
139    }
140
141    /// Set the pgxs
142    #[must_use]
143    pub fn pgxs(mut self) -> Self {
144        self.pgxs = true;
145        self
146    }
147
148    /// Set the configure flag
149    #[must_use]
150    pub fn configure(mut self) -> Self {
151        self.configure = true;
152        self
153    }
154
155    /// Set the cc flag
156    #[must_use]
157    pub fn cc(mut self) -> Self {
158        self.cc = true;
159        self
160    }
161
162    /// Set the cppflags flag
163    #[must_use]
164    pub fn cppflags(mut self) -> Self {
165        self.cppflags = true;
166        self
167    }
168
169    /// Set the cflags flag
170    #[must_use]
171    pub fn cflags(mut self) -> Self {
172        self.cflags = true;
173        self
174    }
175
176    /// Set the `cflags_sl` flag
177    #[must_use]
178    pub fn cflags_sl(mut self) -> Self {
179        self.cflags_sl = true;
180        self
181    }
182
183    /// Set the ldflags flag
184    #[must_use]
185    pub fn ldflags(mut self) -> Self {
186        self.ldflags = true;
187        self
188    }
189
190    /// Set the `ldflags_ex` flag
191    #[must_use]
192    pub fn ldflags_ex(mut self) -> Self {
193        self.ldflags_ex = true;
194        self
195    }
196
197    /// Set the `ldflags_sl` flag
198    #[must_use]
199    pub fn ldflags_sl(mut self) -> Self {
200        self.ldflags_sl = true;
201        self
202    }
203
204    /// Set the libs flag
205    #[must_use]
206    pub fn libs(mut self) -> Self {
207        self.libs = true;
208        self
209    }
210
211    /// output version information, then exit
212    #[must_use]
213    pub fn version(mut self) -> Self {
214        self.version = true;
215        self
216    }
217
218    /// show help, then exit
219    #[must_use]
220    pub fn help(mut self) -> Self {
221        self.help = true;
222        self
223    }
224}
225
226impl CommandBuilder for PgConfigBuilder {
227    /// Get the program name
228    fn get_program(&self) -> &'static OsStr {
229        "pg_config".as_ref()
230    }
231
232    /// Location of the program binary
233    fn get_program_dir(&self) -> &Option<PathBuf> {
234        &self.program_dir
235    }
236
237    /// Get the arguments for the command
238    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    /// Get the environment variables for the command
341    fn get_envs(&self) -> Vec<(OsString, OsString)> {
342        self.envs.clone()
343    }
344
345    /// Set an environment variable for the command
346    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}