use std::path::Path;
use serde_json::Value;
use crate::core::server::constant::ROOT_DIRECTORY_FILE_NAME;
pub const JSON_COMPATIBLE_EXTENSIONS: [&str; 3] = ["json", "json5", "csv"];
pub fn resolve_with_json_compatible_extensions(unknown_path: &str) -> Option<String> {
let p = Path::new(unknown_path);
if p.is_file() {
return Some(unknown_path.to_owned());
}
for ext in JSON_COMPATIBLE_EXTENSIONS {
let with_ext = format!("{}.{}", unknown_path, ext);
if Path::new(&with_ext).is_file() {
return Some(with_ext);
}
}
for ext in JSON_COMPATIBLE_EXTENSIONS {
let p = Path::new(unknown_path).join(format!("{}.{}", ROOT_DIRECTORY_FILE_NAME, ext));
if p.is_file() {
return p
.canonicalize()
.ok()
.and_then(|c| c.to_str().map(|s| s.to_owned()));
}
}
let p = Path::new(unknown_path).join(format!("{}.html", ROOT_DIRECTORY_FILE_NAME));
if p.is_file() {
return p
.canonicalize()
.ok()
.and_then(|c| c.to_str().map(|s| s.to_owned()));
}
None
}
pub fn is_equivalent_json_file(request_path: &Path, entry_path: &Path) -> bool {
let Some(request_file_stem) = request_path.file_stem() else {
return false;
};
let Some(entry_file_stem) = entry_path.file_stem() else {
return false;
};
let request_ext = request_path.extension().unwrap_or_default().to_ascii_lowercase();
let entry_ext = entry_path.extension().unwrap_or_default().to_ascii_lowercase();
let Some(request_ext_str) = request_ext.to_str() else {
return false;
};
let Some(entry_ext_str) = entry_ext.to_str() else {
return false;
};
request_file_stem == entry_file_stem
&& JSON_COMPATIBLE_EXTENSIONS.contains(&request_ext_str)
&& JSON_COMPATIBLE_EXTENSIONS.contains(&entry_ext_str)
}
pub fn json_value_by_jsonpath<'a>(value: &'a Value, jsonpath: &str) -> Option<&'a Value> {
jsonpath
.split('.')
.fold(Some(value), |current, key| match current {
Some(Value::Object(map)) => map.get(key),
Some(Value::Array(arr)) => key.parse::<usize>().ok().and_then(|i| arr.get(i)),
_ => None,
})
}