use crate::vsi::unlink_mem_file;
use crate::{Dataset, DatasetOptions};
use gdal_sys::GDALAccess;
use std::ffi::c_void;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
use tempfile::TempPath;
pub struct TempFixture {
_temp_dir: tempfile::TempDir,
temp_path: PathBuf,
}
impl TempFixture {
pub fn fixture(name: &str) -> Self {
let staging = Self::empty(name);
let source = Path::new("fixtures").join(name);
std::fs::copy(source, &staging.temp_path).unwrap();
staging
}
pub fn empty(name: &str) -> Self {
let _temp_dir = tempfile::tempdir().unwrap();
let temp_path = _temp_dir.path().join(name);
Self {
_temp_dir,
temp_path,
}
}
pub fn path(&self) -> &Path {
&self.temp_path
}
}
impl AsRef<Path> for TempFixture {
fn as_ref(&self) -> &Path {
self.path()
}
}
pub fn fixture(filename: &str) -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("fixtures")
.join(filename)
}
pub struct InMemoryFixture {
path: PathBuf,
}
impl InMemoryFixture {
pub fn new(filename: &str) -> Self {
let mut path = PathBuf::from("/vsimem");
path.push(filename);
Self { path }
}
pub fn path(&self) -> &Path {
&self.path
}
}
impl Drop for InMemoryFixture {
fn drop(&mut self) {
unlink_mem_file(&self.path).expect("unable to remove in-memory file");
}
}
pub(crate) struct SuppressGDALErrorLog {
_private: PhantomData<*mut c_void>,
}
impl SuppressGDALErrorLog {
pub(crate) fn new() -> Self {
unsafe { gdal_sys::CPLPushErrorHandler(Some(gdal_sys::CPLQuietErrorHandler)) };
SuppressGDALErrorLog {
_private: PhantomData,
}
}
}
impl Drop for SuppressGDALErrorLog {
fn drop(&mut self) {
unsafe { gdal_sys::CPLPopErrorHandler() };
}
}
pub fn open_gpkg_for_update(path: &Path) -> (TempPath, Dataset) {
use std::fs;
use std::io::Write;
let input_data = fs::read(path).unwrap();
let (mut file, temp_path) = tempfile::Builder::new()
.suffix(".gpkg")
.tempfile()
.unwrap()
.into_parts();
file.write_all(&input_data).unwrap();
drop(file);
let ds = Dataset::open_ex(
&temp_path,
DatasetOptions {
open_flags: GDALAccess::GA_Update.into(),
allowed_drivers: Some(&["GPKG"]),
..DatasetOptions::default()
},
)
.unwrap();
(temp_path, ds)
}
#[macro_export]
macro_rules! assert_near {
($left:expr, $right:expr) => {
assert_near!($left, $right, epsilon = f64::EPSILON)
};
($left:expr, $right:expr, epsilon = $ep:expr) => {
assert!(
($left - $right).abs() < $ep,
"|{} - {}| = {} is greater than epsilon {:.4e}",
$left,
$right,
($left - $right).abs(),
$ep
)
};
($left:expr, $right:expr, epsilon = $ep:expr, field = $field:expr) => {
assert!(
($left - $right).abs() < $ep,
"field {}: |{} - {}| = {} is greater than epsilon {:.4e}",
$field,
$left,
$right,
($left - $right).abs(),
$ep
)
};
(StatisticsAll, $left:expr, $right:expr, epsilon = $ep:expr) => {
assert_near!($left.min, $right.min, epsilon = $ep, field = "min");
assert_near!($left.max, $right.max, epsilon = $ep, field = "max");
assert_near!($left.mean, $right.mean, epsilon = $ep, field = "mean");
assert_near!(
$left.std_dev,
$right.std_dev,
epsilon = $ep,
field = "std_dev"
);
};
}