use super::constants::{
KNOWN_CONSTANT_PREFIXES, KNOWN_CONSTANT_SUFFIXES, KNOWN_PURE_STD_FUNCTIONS, PURE_METHOD_NAMES,
};
use super::types::PathPurity;
pub fn is_known_pure_call(method_name: &str, receiver_type: Option<&str>) -> bool {
let full_name = match receiver_type {
Some(ty) => format!("{}::{}", ty, method_name),
None => method_name.to_string(),
};
KNOWN_PURE_STD_FUNCTIONS
.iter()
.any(|pure_fn| full_name.ends_with(pure_fn) || pure_fn.ends_with(&full_name))
}
pub fn is_known_pure_method(method_name: &str) -> bool {
PURE_METHOD_NAMES.contains(&method_name)
}
pub fn is_known_constant(path_str: &str) -> bool {
for prefix in KNOWN_CONSTANT_PREFIXES {
if path_str.starts_with(prefix) {
return true;
}
}
for suffix in KNOWN_CONSTANT_SUFFIXES {
if path_str.ends_with(suffix) {
return true;
}
}
false
}
pub fn is_screaming_case(s: &str) -> bool {
!s.is_empty()
&& s.chars()
.all(|c| c.is_uppercase() || c == '_' || c.is_numeric())
&& s.chars().any(|c| c.is_alphabetic())
}
pub fn is_pascal_case(s: &str) -> bool {
s.chars().next().is_some_and(|c| c.is_uppercase())
&& !s.chars().all(|c| c.is_uppercase() || c == '_')
&& s.chars().any(|c| c.is_lowercase())
}
pub fn classify_path_purity(path_str: &str) -> PathPurity {
if is_known_constant(path_str) {
return PathPurity::Constant;
}
let last_segment = path_str.rsplit("::").next().unwrap_or(path_str).trim();
if is_screaming_case(last_segment) {
return PathPurity::ProbablyConstant;
}
if is_pascal_case(last_segment) {
let segments: Vec<&str> = path_str.split("::").map(|s| s.trim()).collect();
if segments.len() >= 2 {
return PathPurity::ProbablyConstant;
}
}
PathPurity::Unknown
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_known_pure_call_option_map() {
assert!(is_known_pure_call("map", Some("Option")));
assert!(is_known_pure_call("and_then", Some("Option")));
assert!(is_known_pure_call("unwrap_or", Some("Option")));
}
#[test]
fn test_is_known_pure_call_result_methods() {
assert!(is_known_pure_call("map", Some("Result")));
assert!(is_known_pure_call("map_err", Some("Result")));
assert!(is_known_pure_call("and_then", Some("Result")));
assert!(is_known_pure_call("is_ok", Some("Result")));
}
#[test]
fn test_is_known_pure_call_iterator_methods() {
assert!(is_known_pure_call("map", Some("Iterator")));
assert!(is_known_pure_call("filter", Some("Iterator")));
assert!(is_known_pure_call("fold", Some("Iterator")));
assert!(is_known_pure_call("collect", Some("Iterator")));
assert!(is_known_pure_call("sum", Some("Iterator")));
}
#[test]
fn test_is_known_pure_method_without_receiver() {
assert!(is_known_pure_method("map"));
assert!(is_known_pure_method("filter"));
assert!(is_known_pure_method("collect"));
assert!(is_known_pure_method("len"));
assert!(is_known_pure_method("is_empty"));
assert!(is_known_pure_method("clone"));
}
#[test]
fn test_is_known_pure_method_unknown() {
assert!(!is_known_pure_method("println"));
assert!(!is_known_pure_method("write"));
assert!(!is_known_pure_method("push")); assert!(!is_known_pure_method("insert")); }
#[test]
fn test_is_screaming_case() {
assert!(is_screaming_case("MAX"));
assert!(is_screaming_case("MIN_VALUE"));
assert!(is_screaming_case("MAX_SIZE"));
assert!(!is_screaming_case("maxValue"));
assert!(!is_screaming_case("MaxValue"));
assert!(!is_screaming_case(""));
}
#[test]
fn test_is_pascal_case() {
assert!(is_pascal_case("Option"));
assert!(is_pascal_case("MyEnum"));
assert!(is_pascal_case("SomeValue"));
assert!(!is_pascal_case("MAX"));
assert!(!is_pascal_case("max_value"));
assert!(!is_pascal_case(""));
}
#[test]
fn test_classify_path_purity_constant() {
assert_eq!(
classify_path_purity("std :: i32 :: MAX"),
PathPurity::Constant
);
assert_eq!(
classify_path_purity("core :: u64 :: MIN"),
PathPurity::Constant
);
}
#[test]
fn test_classify_path_purity_probably_constant() {
assert_eq!(
classify_path_purity("config :: MAX_SIZE"),
PathPurity::ProbablyConstant
);
assert_eq!(
classify_path_purity("Option :: None"),
PathPurity::ProbablyConstant
);
}
#[test]
fn test_classify_path_purity_unknown() {
assert_eq!(
classify_path_purity("external :: get_value"),
PathPurity::Unknown
);
}
}