perf: eliminate unnecessary clones and improve API ergonomics

- PromptBuilder::new now takes &[String] instead of Vec<String>
- GeminiClient::new now takes &str, &[String] instead of owned values
- FileBatch::from_path now takes &Path instead of PathBuf
- categorize_files_offline now takes Vec<String> (ownership) instead of &[String]
- handle_offline_organization now takes FileBatch by value

These changes eliminate ~5-50 KB of unnecessary allocations for typical
file counts, reduce allocator pressure, and improve API clarity by properly
expressing ownership semantics.

No functional changes - all tests pass.
This commit is contained in:
2026-01-08 23:42:10 +05:30
parent eeb07983cb
commit ba0ea3f221
8 changed files with 32 additions and 25 deletions

View File

@@ -120,21 +120,21 @@ pub struct OfflineCategorizationResult {
/// Categorizes a list of filenames using extension-based rules.
/// Returns categorized files and a list of skipped filenames.
pub fn categorize_files_offline(filenames: &[String]) -> OfflineCategorizationResult {
pub fn categorize_files_offline(filenames: Vec<String>) -> OfflineCategorizationResult {
let mut files = Vec::with_capacity(filenames.len());
let mut skipped = Vec::new();
for filename in filenames {
match categorize_by_extension(filename) {
match categorize_by_extension(&filename) {
Some(category) => {
files.push(FileCategory {
filename: filename.clone(),
filename,
category: category.to_string(),
sub_category: String::new(),
});
}
None => {
skipped.push(filename.clone());
skipped.push(filename);
}
}
}
@@ -187,7 +187,7 @@ mod tests {
"file.xyz".to_string(),
];
let result = categorize_files_offline(&filenames);
let result = categorize_files_offline(filenames);
assert_eq!(result.plan.files.len(), 2);
assert_eq!(result.skipped.len(), 2);