use crate::Settings;
use crate::traits::CommandBuilder;
use std::convert::AsRef;
use std::ffi::{OsStr, OsString};
use std::path::PathBuf;
#[derive(Clone, Debug, Default)]
pub struct PgConfigBuilder {
program_dir: Option<PathBuf>,
envs: Vec<(OsString, OsString)>,
bindir: bool,
docdir: bool,
htmldir: bool,
includedir: bool,
pkgincludedir: bool,
includedir_server: bool,
libdir: bool,
pkglibdir: bool,
localedir: bool,
mandir: bool,
sharedir: bool,
sysconfdir: bool,
pgxs: bool,
configure: bool,
cc: bool,
cppflags: bool,
cflags: bool,
cflags_sl: bool,
ldflags: bool,
ldflags_ex: bool,
ldflags_sl: bool,
libs: bool,
version: bool,
help: bool,
}
impl PgConfigBuilder {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn from(settings: &dyn Settings) -> Self {
Self::new().program_dir(settings.get_binary_dir())
}
#[must_use]
pub fn program_dir<P: Into<PathBuf>>(mut self, path: P) -> Self {
self.program_dir = Some(path.into());
self
}
#[must_use]
pub fn bindir(mut self) -> Self {
self.bindir = true;
self
}
#[must_use]
pub fn docdir(mut self) -> Self {
self.docdir = true;
self
}
#[must_use]
pub fn htmldir(mut self) -> Self {
self.htmldir = true;
self
}
#[must_use]
pub fn includedir(mut self) -> Self {
self.includedir = true;
self
}
#[must_use]
pub fn pkgincludedir(mut self) -> Self {
self.pkgincludedir = true;
self
}
#[must_use]
pub fn includedir_server(mut self) -> Self {
self.includedir_server = true;
self
}
#[must_use]
pub fn libdir(mut self) -> Self {
self.libdir = true;
self
}
#[must_use]
pub fn pkglibdir(mut self) -> Self {
self.pkglibdir = true;
self
}
#[must_use]
pub fn localedir(mut self) -> Self {
self.localedir = true;
self
}
#[must_use]
pub fn mandir(mut self) -> Self {
self.mandir = true;
self
}
#[must_use]
pub fn sharedir(mut self) -> Self {
self.sharedir = true;
self
}
#[must_use]
pub fn sysconfdir(mut self) -> Self {
self.sysconfdir = true;
self
}
#[must_use]
pub fn pgxs(mut self) -> Self {
self.pgxs = true;
self
}
#[must_use]
pub fn configure(mut self) -> Self {
self.configure = true;
self
}
#[must_use]
pub fn cc(mut self) -> Self {
self.cc = true;
self
}
#[must_use]
pub fn cppflags(mut self) -> Self {
self.cppflags = true;
self
}
#[must_use]
pub fn cflags(mut self) -> Self {
self.cflags = true;
self
}
#[must_use]
pub fn cflags_sl(mut self) -> Self {
self.cflags_sl = true;
self
}
#[must_use]
pub fn ldflags(mut self) -> Self {
self.ldflags = true;
self
}
#[must_use]
pub fn ldflags_ex(mut self) -> Self {
self.ldflags_ex = true;
self
}
#[must_use]
pub fn ldflags_sl(mut self) -> Self {
self.ldflags_sl = true;
self
}
#[must_use]
pub fn libs(mut self) -> Self {
self.libs = true;
self
}
#[must_use]
pub fn version(mut self) -> Self {
self.version = true;
self
}
#[must_use]
pub fn help(mut self) -> Self {
self.help = true;
self
}
}
impl CommandBuilder for PgConfigBuilder {
fn get_program(&self) -> &'static OsStr {
"pg_config".as_ref()
}
fn get_program_dir(&self) -> &Option<PathBuf> {
&self.program_dir
}
fn get_args(&self) -> Vec<OsString> {
let mut args: Vec<OsString> = Vec::new();
if self.bindir {
args.push("--bindir".into());
}
if self.docdir {
args.push("--docdir".into());
}
if self.htmldir {
args.push("--htmldir".into());
}
if self.includedir {
args.push("--includedir".into());
}
if self.pkgincludedir {
args.push("--pkgincludedir".into());
}
if self.includedir_server {
args.push("--includedir-server".into());
}
if self.libdir {
args.push("--libdir".into());
}
if self.pkglibdir {
args.push("--pkglibdir".into());
}
if self.localedir {
args.push("--localedir".into());
}
if self.mandir {
args.push("--mandir".into());
}
if self.sharedir {
args.push("--sharedir".into());
}
if self.sysconfdir {
args.push("--sysconfdir".into());
}
if self.pgxs {
args.push("--pgxs".into());
}
if self.configure {
args.push("--configure".into());
}
if self.cc {
args.push("--cc".into());
}
if self.cppflags {
args.push("--cppflags".into());
}
if self.cflags {
args.push("--cflags".into());
}
if self.cflags_sl {
args.push("--cflags_sl".into());
}
if self.ldflags {
args.push("--ldflags".into());
}
if self.ldflags_ex {
args.push("--ldflags_ex".into());
}
if self.ldflags_sl {
args.push("--ldflags_sl".into());
}
if self.libs {
args.push("--libs".into());
}
if self.version {
args.push("--version".into());
}
if self.help {
args.push("--help".into());
}
args
}
fn get_envs(&self) -> Vec<(OsString, OsString)> {
self.envs.clone()
}
fn env<S: AsRef<OsStr>>(mut self, key: S, value: S) -> Self {
self.envs
.push((key.as_ref().to_os_string(), value.as_ref().to_os_string()));
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::TestSettings;
use crate::traits::CommandToString;
use test_log::test;
#[test]
fn test_builder_new() {
let command = PgConfigBuilder::new().program_dir(".").build();
assert_eq!(
PathBuf::from(".").join("pg_config"),
PathBuf::from(command.to_command_string().replace('"', ""))
);
}
#[test]
fn test_builder_from() {
let command = PgConfigBuilder::from(&TestSettings).build();
#[cfg(not(target_os = "windows"))]
let command_prefix = r#""./pg_config""#;
#[cfg(target_os = "windows")]
let command_prefix = r#"".\\pg_config""#;
assert_eq!(format!("{command_prefix}"), command.to_command_string());
}
#[test]
fn test_builder() {
let command = PgConfigBuilder::new()
.env("PGDATABASE", "database")
.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()
.build();
#[cfg(not(target_os = "windows"))]
let command_prefix = r#"PGDATABASE="database" "#;
#[cfg(target_os = "windows")]
let command_prefix = String::new();
assert_eq!(
format!(
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""#
),
command.to_command_string()
);
}
}