use crate::hir::{HirExpr, Literal};
use std::collections::HashSet;
use syn::parse_quote;
#[allow(dead_code)]
pub fn extract_pattern_arg(
hir_arg: &HirExpr,
rust_arg: &syn::Expr,
fn_str_params: &HashSet<String>,
) -> syn::Expr {
match hir_arg {
HirExpr::Literal(Literal::String(s)) => parse_quote! { #s },
HirExpr::Var(name) if fn_str_params.contains(name) => rust_arg.clone(),
_ => {
parse_quote! { &#rust_arg }
}
}
}
#[allow(dead_code)]
pub fn is_char_variable_name(name: &str) -> bool {
matches!(name, "char" | "ch" | "c" | "character")
}
#[allow(dead_code)]
pub fn simple_string_method(method: &str) -> Option<&'static str> {
match method {
"upper" => Some("to_uppercase"),
"lower" => Some("to_lowercase"),
"title" => Some("to_titlecase"), "swapcase" => Some("to_swapcase"), "casefold" => Some("to_lowercase"), "isalpha" => Some("chars().all(|c| c.is_alphabetic())"),
"isdigit" => Some("chars().all(|c| c.is_ascii_digit())"),
"isalnum" => Some("chars().all(|c| c.is_alphanumeric())"),
"isspace" => Some("chars().all(|c| c.is_whitespace())"),
"isupper" => Some("chars().all(|c| c.is_uppercase())"),
"islower" => Some("chars().all(|c| c.is_lowercase())"),
"isascii" => Some("is_ascii()"),
_ => None,
}
}
#[allow(dead_code)]
pub fn trim_string_method(method: &str) -> Option<&'static str> {
match method {
"strip" => Some("trim().to_string()"),
"lstrip" => Some("trim_start().to_string()"),
"rstrip" => Some("trim_end().to_string()"),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_char_variable_name() {
assert!(is_char_variable_name("char"));
assert!(is_char_variable_name("ch"));
assert!(is_char_variable_name("c"));
assert!(is_char_variable_name("character"));
assert!(!is_char_variable_name("x"));
assert!(!is_char_variable_name("letter"));
}
#[test]
fn test_simple_string_method() {
assert_eq!(simple_string_method("upper"), Some("to_uppercase"));
assert_eq!(simple_string_method("lower"), Some("to_lowercase"));
assert_eq!(
simple_string_method("isalpha"),
Some("chars().all(|c| c.is_alphabetic())")
);
assert_eq!(simple_string_method("unknown"), None);
}
#[test]
fn test_trim_string_method() {
assert_eq!(trim_string_method("strip"), Some("trim().to_string()"));
assert_eq!(
trim_string_method("lstrip"),
Some("trim_start().to_string()")
);
assert_eq!(trim_string_method("rstrip"), Some("trim_end().to_string()"));
assert_eq!(trim_string_method("unknown"), None);
}
#[test]
fn test_extract_pattern_arg_with_literal() {
let hir_arg = HirExpr::Literal(Literal::String("test".to_string()));
let rust_arg: syn::Expr = parse_quote! { test };
let fn_str_params = HashSet::new();
let result = extract_pattern_arg(&hir_arg, &rust_arg, &fn_str_params);
let result_str = quote::quote!(#result).to_string();
assert!(
result_str.contains("test"),
"Expected literal, got: {}",
result_str
);
}
#[test]
fn test_extract_pattern_arg_with_str_param() {
let hir_arg = HirExpr::Var("prefix".to_string());
let rust_arg: syn::Expr = parse_quote! { prefix };
let mut fn_str_params = HashSet::new();
fn_str_params.insert("prefix".to_string());
let result = extract_pattern_arg(&hir_arg, &rust_arg, &fn_str_params);
let result_str = quote::quote!(#result).to_string();
assert!(
result_str.contains("prefix"),
"Expected var, got: {}",
result_str
);
assert!(!result_str.contains("&"), "Should not borrow &str param");
}
#[test]
fn test_extract_pattern_arg_with_owned_string() {
let hir_arg = HirExpr::Var("pattern".to_string());
let rust_arg: syn::Expr = parse_quote! { pattern };
let fn_str_params = HashSet::new();
let result = extract_pattern_arg(&hir_arg, &rust_arg, &fn_str_params);
let result_str = quote::quote!(#result).to_string();
assert!(
result_str.contains("&"),
"Should borrow owned String, got: {}",
result_str
);
}
}