use std::path::Path;
pub fn detect_server_bin() -> String {
let patterns = [
"/opt/homebrew/Caskroom/redis-stack-server/*/bin/redis-server",
"/usr/local/Caskroom/redis-stack-server/*/bin/redis-server",
];
for pattern in &patterns {
if let Ok(mut paths) = glob::glob(pattern)
&& let Some(Ok(path)) = paths.next()
&& let Some(s) = path.to_str()
{
return s.to_string();
}
}
"redis-server".to_string()
}
pub fn detect_stack_modules(server_bin: &str) -> Vec<String> {
let bin_path = Path::new(server_bin);
let lib_dir = match bin_path.parent().and_then(|p| p.parent()) {
Some(base) => base.join("lib"),
None => return Vec::new(),
};
if !lib_dir.is_dir() {
return Vec::new();
}
let modules: &[(&str, &[&str])] = &[
("rediscompat.so", &[]),
(
"redisearch.so",
&["MAXSEARCHRESULTS", "10000", "MAXAGGREGATERESULTS", "10000"],
),
("redistimeseries.so", &[]),
("rejson.so", &[]),
("redisbloom.so", &[]),
];
let mut args: Vec<String> = Vec::new();
for (filename, extra) in modules {
let module_path = lib_dir.join(filename);
if module_path.is_file() {
args.push("--loadmodule".to_string());
args.push(module_path.to_string_lossy().into_owned());
for arg in *extra {
args.push(arg.to_string());
}
}
}
args
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn detect_server_bin_fallback() {
let bin = detect_server_bin();
assert!(!bin.is_empty());
}
#[test]
fn detect_stack_modules_missing_lib() {
let args = detect_stack_modules("redis-server");
assert!(args.is_empty());
}
#[test]
fn detect_stack_modules_nonexistent_path() {
let args = detect_stack_modules("/nonexistent/bin/redis-server");
assert!(args.is_empty());
}
}