use crate::compsys::ported::shared::zstyle_t;
use crate::ported::exec::{dispatch_function_call, execute_script_zsh_pipeline};
use crate::ported::modules::zutil::lookupstyle;
use crate::ported::params::getsparam;
use crate::ported::utils::quotestring;
use crate::ported::zsh_h::QT_SINGLE;
fn call_cache_policy(policy: &str, cache_path: &str) -> i32 {
if let Some(rc) = dispatch_function_call(policy, &[cache_path.to_string()]) {
return rc;
}
let src = format!(
"{}{} {}",
"\n".repeat(18),
quotestring(policy, QT_SINGLE),
quotestring(cache_path, QT_SINGLE)
);
execute_script_zsh_pipeline(&src).unwrap_or(1)
}
pub fn _cache_invalid(args: &[String]) -> i32 {
crate::compsys::ported::shared::call_compfn("_cache_invalid", args, || {
_cache_invalid_impl(args)
})
}
pub fn _cache_invalid_impl(args: &[String]) -> i32 {
let _fn_scope = crate::compsys::ported::shared::FnScope::enter("_cache_invalid");
let cache_ident = args.first().cloned().unwrap_or_default();
let curcontext = getsparam("curcontext").unwrap_or_default();
let ctx = format!(":completion:{}:", curcontext);
if zstyle_t(&ctx, "use-cache") != 0 {
return 1;
}
let cache_dir = lookupstyle(&ctx, "cache-path")
.first()
.cloned()
.unwrap_or_else(|| {
let home = getsparam("ZDOTDIR")
.filter(|s| !s.is_empty())
.or_else(|| getsparam("HOME"))
.unwrap_or_default();
format!("{}/.zcompcache", home)
});
let cache_path = format!("{}/{}", cache_dir, cache_ident);
let policy = lookupstyle(&ctx, "cache-policy")
.first()
.cloned()
.unwrap_or_default();
if !policy.is_empty() && call_cache_policy(&policy, &cache_path) == 0 {
return 0;
}
1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn returns_one_when_use_cache_disabled() {
let _g = crate::test_util::global_state_lock();
assert_eq!(_cache_invalid_impl(&["my-cache".to_string()]), 1);
}
#[test]
fn use_cache_zero_skips_the_policy_hook() {
let _g = crate::test_util::global_state_lock();
let ops = crate::ported::zsh_h::options {
ind: [0u8; crate::ported::zsh_h::MAX_OPS],
args: Vec::new(),
argscount: 0,
argsalloc: 0,
};
let ctx = ":completion:cizero:cizero:cizero:";
let _ = crate::ported::params::setsparam("curcontext", "cizero:cizero:cizero");
for (style, val) in [("use-cache", "0"), ("cache-policy", "true")] {
crate::ported::modules::zutil::bin_zstyle(
"zstyle",
&[ctx.to_string(), style.to_string(), val.to_string()],
&ops,
0,
);
}
let rc = _cache_invalid_impl(&["ciz-ident".to_string()]);
for style in ["use-cache", "cache-policy"] {
crate::ported::modules::zutil::bin_zstyle(
"zstyle",
&["-d".to_string(), ctx.to_string(), style.to_string()],
&ops,
0,
);
}
crate::ported::params::unsetparam("curcontext");
assert_eq!(
rc, 1,
"sh:10 — `use-cache 0` returns 1 before the always-stale policy runs"
);
}
}