use crate::utils::_string;
use std::collections::HashMap;
use std::ffi::CString;
use std::fmt::Write;
pub fn version_info(key: &str) -> String {
let c_key = CString::new(key.as_bytes()).unwrap();
let rv = unsafe { gdal_sys::GDALVersionInfo(c_key.as_ptr()) };
_string(rv).unwrap_or_default()
}
pub struct VersionInfo;
impl VersionInfo {
pub fn version_summary() -> String {
version_info("--version")
}
pub fn version_num() -> String {
version_info("VERSION_NUM")
}
pub fn release_date() -> String {
version_info("RELEASE_DATE")
}
pub fn release_name() -> String {
version_info("RELEASE_NAME")
}
pub fn license() -> String {
version_info("LICENSE")
}
pub fn build_info() -> HashMap<String, String> {
let text = version_info("BUILD_INFO");
text.lines()
.filter_map(|l| l.split_once('='))
.map(|p| (p.0.to_string(), p.1.to_string()))
.collect()
}
pub fn has_geos() -> bool {
version_info("BUILD_INFO").contains("GEOS_ENABLED=YES")
}
pub fn version_report() -> String {
let mut buff: String = "GDALVersionInfo {\n".into();
fn kv(buff: &mut String, l: usize, k: &str, v: &str) {
writeln!(buff, "{:indent$}{k}: \"{v}\"", " ", indent = l * 4).unwrap();
}
kv(&mut buff, 1, "RELEASE_NAME", &Self::release_name());
kv(&mut buff, 1, "RELEASE_DATE", &Self::release_date());
kv(&mut buff, 1, "VERSION_NUM", &Self::version_num());
buff.push_str(" BUILD_INFO {\n");
Self::build_info()
.iter()
.for_each(|(k, v)| kv(&mut buff, 2, k, v));
buff.push_str(" }\n");
buff.push('}');
buff
}
}
#[cfg(test)]
mod tests {
use super::version_info;
use crate::version::VersionInfo;
#[test]
fn test_version_info() {
let release_date = version_info("RELEASE_DATE");
let release_name = version_info("RELEASE_NAME");
let mut release_nickname = version_info("RELEASE_NICKNAME");
let xyzzy = version_info("XYZZY");
let version_text = version_info("--version");
let mut date_iter = release_date.chars();
if release_nickname != xyzzy {
release_nickname = format!(r#" "{release_nickname}""#)
} else {
release_nickname.clear();
}
let expected_text: String = format!(
"GDAL {release_name}{release_nickname}, released {}/{}/{}",
date_iter.by_ref().take(4).collect::<String>(),
date_iter.by_ref().take(2).collect::<String>(),
date_iter.by_ref().take(2).collect::<String>(),
);
assert_eq!(
version_text
.strip_suffix(" (debug build)")
.unwrap_or(&version_text),
&expected_text
);
}
#[test]
fn test_version_info_functions() {
let rel_name = VersionInfo::release_name();
assert!(!rel_name.is_empty());
let build = VersionInfo::build_info();
assert!(!build.is_empty());
let rpt = VersionInfo::version_report();
assert!(rpt.contains(&rel_name));
let license = VersionInfo::license();
assert!(!license.is_empty());
}
#[test]
fn test_has_geos() {
let has_geos = VersionInfo::build_info()
.get("GEOS_ENABLED")
.unwrap_or(&"NO".into())
== "YES";
assert_eq!(VersionInfo::has_geos(), has_geos);
}
}