use core_foundation as cf;
use self::cf::base::TCFType;
use crate::error::Error;
use crate::error::Error::{IncompatiblePathCharset, SystemCallFailed};
use std::path::Path;
use std::ptr;
pub fn exclude_from_backups<P: AsRef<Path>>(path: P) -> Result<(), Error> {
let url = cf::url::CFURL::from_path(path, false).ok_or(IncompatiblePathCharset)?;
unsafe {
let mut err = ptr::null_mut();
cf::url::CFURLSetResourcePropertyForKey(
url.as_concrete_TypeRef(),
cf::url::kCFURLIsExcludedFromBackupKey,
cf::number::kCFBooleanTrue.cast(),
&mut err,
);
if !err.is_null() {
let err: cf::error::CFError = TCFType::wrap_under_create_rule(err);
return Err(SystemCallFailed(err.to_string().into()));
}
}
Ok(())
}
#[test]
fn test_excluding() {
use std::fs;
use std::process::Command;
let path = Path::new("/tmp/exclude_from_backups_test_dir");
if !path.exists() {
fs::create_dir(path).unwrap();
}
exclude_from_backups(path).unwrap();
let out = Command::new("xattr")
.arg("-p")
.arg("com.apple.metadata:com_apple_backup_excludeItem")
.arg(path)
.output()
.unwrap();
assert!(out.status.success());
let _ = fs::remove_dir_all(path);
}