use std::process::Command;
use log::debug;
use regex::Regex;
use crate::{cli::sh_run, config::ConfigEnv};
pub fn get_re_safe_check_path() -> Regex {
Regex::new(r"/\.pmbs/[1-9][0-9]{3,}/[1-9][0-9]{9,}$").unwrap()
}
pub fn safe_rm_subvol_list(config: &ConfigEnv, list: Vec<String>) {
let re = get_re_safe_check_path();
for i in list {
debug!("check {}", i);
if re.is_match(&i) {
let mut c = Command::new(config.bin_btrfs.clone());
c.arg("subvol").arg("delete").arg(&i);
let code = sh_run(c);
if 0 != code {
panic!("can not rm subvol {}", i);
}
} else {
panic!("bad subvol path {}", i);
}
}
}
#[cfg(test)]
mod test_re {
use super::*;
#[test]
fn re_should_match() {
let re = get_re_safe_check_path();
assert_eq!(re.is_match("/home/.pmbs/2025/1756392923"), true);
assert_eq!(re.is_match("/.pmbs/2025/1756392923"), true);
assert_eq!(re.is_match("/.pmbs/9999/1756392923"), true);
assert_eq!(re.is_match("/.pmbs/2025/9999999999"), true);
assert_eq!(re.is_match("/.pmbs/10000/20000000000"), true);
}
#[test]
fn re_not_match_empty() {
let re = get_re_safe_check_path();
assert_eq!(re.is_match(""), false);
assert_eq!(re.is_match("/"), false);
assert_eq!(re.is_match("/.pmbs"), false);
assert_eq!(re.is_match("/.pmbs/"), false);
assert_eq!(re.is_match("/.pmbs//1756392923"), false);
assert_eq!(re.is_match("/.pmbs/2025/"), false);
assert_eq!(re.is_match("/.pmbs/2025"), false);
assert_eq!(re.is_match("/.pmbs/2025"), false);
assert_eq!(re.is_match("/2025/1756392923"), false);
assert_eq!(re.is_match("2025/1756392923"), false);
assert_eq!(re.is_match("//2025/1756392923"), false);
}
#[test]
fn re_not_match_short() {
let re = get_re_safe_check_path();
assert_eq!(re.is_match("/.pmbs/1/1756392923"), false);
assert_eq!(re.is_match("/.pmbs/20/1756392923"), false);
assert_eq!(re.is_match("/.pmbs/202/1756392923"), false);
assert_eq!(re.is_match("/.pmbs/0025/1756392923"), false);
assert_eq!(re.is_match("/.pmbs/2025/175639292"), false);
assert_eq!(re.is_match("/.pmbs/2025/17"), false);
assert_eq!(re.is_match("/.pmbs/2025/56392923"), false);
assert_eq!(re.is_match("/.pmbs/2025/0175639292"), false);
assert_eq!(re.is_match("/pmbs/2025/1756392923"), false);
assert_eq!(re.is_match("/.pbs/2025/1756392923"), false);
assert_eq!(re.is_match("/.pmb/2025/1756392923"), false);
assert_eq!(re.is_match("/.s/2025/1756392923"), false);
assert_eq!(re.is_match("/./2025/1756392923"), false);
}
#[test]
fn re_not_match_system() {
let re = get_re_safe_check_path();
assert_eq!(re.is_match("/"), false);
assert_eq!(re.is_match("/home"), false);
assert_eq!(re.is_match("/usr"), false);
assert_eq!(re.is_match("/var"), false);
assert_eq!(re.is_match("/etc"), false);
assert_eq!(re.is_match("/mnt"), false);
assert_eq!(re.is_match("/srv"), false);
assert_eq!(re.is_match("/root"), false);
assert_eq!(re.is_match("/boot"), false);
}
#[test]
fn re_not_match_char() {
let re = get_re_safe_check_path();
assert_eq!(re.is_match("/.pmbs/2025/1756392923x"), false);
assert_eq!(re.is_match("/.pmbs/2025/c1756392923"), false);
assert_eq!(re.is_match("/.pmbs/2025/.1756392923"), false);
assert_eq!(re.is_match("/.pmbs/2025/175_6392923"), false);
assert_eq!(re.is_match("/.pmbs/2025/17563929-23"), false);
assert_eq!(re.is_match("/.pmbs/.2025/1756392923"), false);
assert_eq!(re.is_match("/.pmbs/2a25/1756392923"), false);
assert_eq!(re.is_match("/.pmbs/202_/1756392923"), false);
assert_eq!(re.is_match("/.pcbs/2025/1756392923"), false);
assert_eq!(re.is_match("/.pmbb/2025/1756392923"), false);
assert_eq!(re.is_match("/apmbs/2025/1756392923"), false);
}
}