Function bodies 405 total
detect_filler_words function · rust · L167-L228 (62 LOC)src-tauri/src/services/filler_detector.rs
pub fn detect_filler_words(
transcription: &Transcription,
config: &FillerDetectionConfig,
) -> Vec<FillerWordDetection> {
let mut detections = Vec::new();
// Build phonetic map for faster lookup
let phonetic_map: HashMap<String, Vec<&str>> = build_phonetic_map();
for word in &transcription.words {
let word_lower = word.word.to_lowercase();
let word_clean = word_clean(&word_lower);
// Skip very short words
if word_clean.len() < 2 {
continue;
}
// Check direct matches
if let Some(filler_type) = find_direct_match(&word_clean) {
if word.confidence >= config.min_confidence {
detections.push(FillerWordDetection {
start: word.start,
end: word.end,
word: filler_type.as_str().to_string(),
confidence: calculate_filler_confidence(&word, &filler_type, &word_clean),
filler_typebuild_phonetic_map function · rust · L233-L242 (10 LOC)src-tauri/src/services/filler_detector.rs
fn build_phonetic_map() -> HashMap<String, Vec<&'static str>> {
let mut map = HashMap::new();
for (filler, _) in FILLER_WORDS {
let encoded = phonetic_encode(filler);
map.entry(encoded).or_insert_with(Vec::new).push(*filler);
}
map
}find_direct_match function · rust · L247-L253 (7 LOC)src-tauri/src/services/filler_detector.rs
fn find_direct_match(word: &str) -> Option<FillerType> {
FILLER_WORDS
.iter()
.find(|(filler, _)| *filler == word)
.map(|(_, filler_type)| filler_type.clone())
.or_else(|| get_additional_filler(word))
}find_filler_type function · rust · L258-L261 (4 LOC)src-tauri/src/services/filler_detector.rs
fn find_filler_type(word: &str) -> FillerType {
find_direct_match(word)
.unwrap_or_else(|| FillerType::Other(word.to_string()))
}word_clean function · rust · L266-L270 (5 LOC)src-tauri/src/services/filler_detector.rs
fn word_clean(word: &str) -> String {
word.chars()
.filter(|c| c.is_alphabetic() || c.is_whitespace())
.collect()
}calculate_filler_confidence function · rust · L280-L301 (22 LOC)src-tauri/src/services/filler_detector.rs
fn calculate_filler_confidence(word: &TimedWord, filler_type: &FillerType, matched: &str) -> f64 {
let base_confidence = word.confidence;
// Boost for exact matches
let match_bonus = if filler_type.as_str() == matched {
0.2
} else {
0.0
};
// Adjust based on word duration (filler words are typically short)
let duration = word.end - word.start;
let duration_factor = if duration < 0.5 {
1.0
} else if duration < 1.0 {
0.9
} else {
0.7
};
(base_confidence + match_bonus).min(1.0) * duration_factor
}calculate_similarity function · rust · L306-L321 (16 LOC)src-tauri/src/services/filler_detector.rs
fn calculate_similarity(a: &str, b: &str) -> f64 {
let a_len = a.chars().count();
let b_len = b.chars().count();
if a_len == 0 && b_len == 0 {
return 1.0;
}
if a_len == 0 || b_len == 0 {
return 0.0;
}
let distance = levenshtein_distance(a, b);
let max_len = a_len.max(b_len);
1.0 - (distance as f64 / max_len as f64)
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
levenshtein_distance function · rust · L326-L363 (38 LOC)src-tauri/src/services/filler_detector.rs
fn levenshtein_distance(a: &str, b: &str) -> usize {
let a_chars: Vec<char> = a.chars().collect();
let b_chars: Vec<char> = b.chars().collect();
let a_len = a_chars.len();
let b_len = b_chars.len();
let mut matrix = vec![vec![0; b_len + 1]; a_len + 1];
// Initialize first row and column
for i in 0..=a_len {
matrix[i][0] = i;
}
for j in 0..=b_len {
matrix[0][j] = j;
}
// Fill matrix
for i in 1..=a_len {
for j in 1..=b_len {
let cost = if a_chars[i - 1] == b_chars[j - 1] {
0
} else {
1
};
matrix[i][j] = [
matrix[i - 1][j] + 1, // deletion
matrix[i][j - 1] + 1, // insertion
matrix[i - 1][j - 1] + cost, // substitution
]
.into_iter()
.min()
.unwrap();
}
}
matrix[a_len][b_len]
}merge_overlapping_detections function · rust · L368-L392 (25 LOC)src-tauri/src/services/filler_detector.rs
fn merge_overlapping_detections(mut detections: Vec<FillerWordDetection>) -> Vec<FillerWordDetection> {
if detections.is_empty() {
return detections;
}
// Sort by start time
detections.sort_by(|a, b| a.start.partial_cmp(&b.start).unwrap());
let mut merged = Vec::new();
let mut current = detections[0].clone();
for detection in detections.into_iter().skip(1) {
if detection.start <= current.end + 0.2 {
// Overlapping or close - merge
current.end = current.end.max(detection.end);
current.confidence = current.confidence.max(detection.confidence);
} else {
merged.push(current);
current = detection;
}
}
merged.push(current);
merged
}create_mock_transcription function · rust · L403-L484 (82 LOC)src-tauri/src/services/filler_detector.rs
pub fn create_mock_transcription(duration: f64) -> Transcription {
let words = vec![
TimedWord {
word: "Hello".into(),
start: 0.0,
end: 0.5,
confidence: 0.98,
},
TimedWord {
word: "um".into(),
start: 0.7,
end: 0.9,
confidence: 0.92,
},
TimedWord {
word: "today".into(),
start: 1.0,
end: 1.3,
confidence: 0.95,
},
TimedWord {
word: "we're".into(),
start: 1.4,
end: 1.7,
confidence: 0.97,
},
TimedWord {
word: "going".into(),
start: 1.8,
end: 2.1,
confidence: 0.96,
},
TimedWord {
word: "to".into(),
start: 2.2,
end: 2.4,
confidence: 0.99,
},
TimedWord {
word: "uh".into(),
start: 2detect_fillers_from_audio function · rust · L494-L527 (34 LOC)src-tauri/src/services/filler_detector.rs
pub fn detect_fillers_from_audio(
_audio_path: &str,
_config: &FillerDetectionConfig,
) -> Result<Vec<FillerWordDetection>, String> {
// Placeholder: Return mock detections
// In production, this would:
// 1. Transcribe audio using Whisper
// 2. Run filler detection on transcription
// 3. Return results
Ok(vec![
FillerWordDetection {
start: 2.0,
end: 2.5,
word: "um".into(),
confidence: 0.92,
filler_type: FillerType::Um,
},
FillerWordDetection {
start: 8.0,
end: 8.4,
word: "uh".into(),
confidence: 0.88,
filler_type: FillerType::Uh,
},
FillerWordDetection {
start: 15.0,
end: 15.5,
word: "like".into(),
confidence: 0.85,
filler_type: FillerType::Like,
},
])
}test_phonetic_encoding function · rust · L534-L544 (11 LOC)src-tauri/src/services/filler_detector.rs
fn test_phonetic_encoding() {
// First character is kept, then consonants only
let encoded = phonetic_encode("um");
assert_eq!(encoded, "um00"); // 'u' is first (vowel kept), 'm' is consonant
let encoded = phonetic_encode("uh");
assert_eq!(encoded.len(), 4); // Normalized to 4 chars
let encoded = phonetic_encode("like");
assert_eq!(encoded.len(), 4);
}test_levenshtein_distance function · rust · L547-L551 (5 LOC)src-tauri/src/services/filler_detector.rs
fn test_levenshtein_distance() {
assert_eq!(levenshtein_distance("um", "um"), 0);
assert_eq!(levenshtein_distance("um", "uh"), 1);
assert_eq!(levenshtein_distance("hello", "hallo"), 1);
}test_similarity_calculation function · rust · L554-L560 (7 LOC)src-tauri/src/services/filler_detector.rs
fn test_similarity_calculation() {
let sim = calculate_similarity("um", "um");
assert_eq!(sim, 1.0);
let sim = calculate_similarity("um", "uh");
assert!(sim > 0.0 && sim < 1.0);
}test_filler_detection function · rust · L563-L577 (15 LOC)src-tauri/src/services/filler_detector.rs
fn test_filler_detection() {
let transcription = create_mock_transcription(5.0);
let config = FillerDetectionConfig::default();
let detections = detect_filler_words(&transcription, &config);
assert!(!detections.is_empty());
// Check that "um" and "uh" are detected
let has_um = detections.iter().any(|d| d.word == "um");
let has_uh = detections.iter().any(|d| d.word == "uh");
assert!(has_um, "Should detect 'um'");
assert!(has_uh, "Should detect 'uh'");
}Repobility — the code-quality scanner for AI-generated software · https://repobility.com
test_direct_match_all_filler_types function · rust · L580-L591 (12 LOC)src-tauri/src/services/filler_detector.rs
fn test_direct_match_all_filler_types() {
// Test direct matching for all filler types
assert!(find_direct_match("um").is_some());
assert!(find_direct_match("uh").is_some());
assert!(find_direct_match("er").is_some());
assert!(find_direct_match("like").is_some());
assert!(find_direct_match("you know").is_some());
assert!(find_direct_match("y'know").is_some());
assert!(find_direct_match("I mean").is_some());
assert!(find_direct_match("actually").is_some());
assert!(find_direct_match("basically").is_some());
}test_phonetic_variations function · rust · L594-L607 (14 LOC)src-tauri/src/services/filler_detector.rs
fn test_phonetic_variations() {
// Test phonetic encoding for common filler variations
let um_variants = vec!["um", "umm", "uum"];
for variant in um_variants {
let encoded = phonetic_encode(variant);
assert!(!encoded.is_empty());
}
let uh_variants = vec!["uh", "uhh", "uuh"];
for variant in uh_variants {
let encoded = phonetic_encode(variant);
assert!(!encoded.is_empty());
}
}test_levenshtein_distance_edge_cases function · rust · L610-L622 (13 LOC)src-tauri/src/services/filler_detector.rs
fn test_levenshtein_distance_edge_cases() {
// Empty strings
assert_eq!(levenshtein_distance("", ""), 0);
assert_eq!(levenshtein_distance("", "test"), 4);
assert_eq!(levenshtein_distance("test", ""), 4);
// Single character
assert_eq!(levenshtein_distance("a", "a"), 0);
assert_eq!(levenshtein_distance("a", "b"), 1);
// Unicode handling (should work with char count)
assert_eq!(levenshtein_distance("café", "cafe"), 1);
}test_similarity_thresholds function · rust · L625-L637 (13 LOC)src-tauri/src/services/filler_detector.rs
fn test_similarity_thresholds() {
// Test similarity calculation at various thresholds
let exact_match = calculate_similarity("um", "um");
assert_eq!(exact_match, 1.0);
let one_char_diff = calculate_similarity("um", "uh");
// "um" and "uh" have 1 character difference out of 2
// Similarity = 1 - (1/2) = 0.5
assert!(one_char_diff >= 0.0 && one_char_diff <= 1.0);
let completely_different = calculate_similarity("um", "like");
assert!(completely_different < 0.5);
}test_confidence_calculation_with_duration function · rust · L640-L654 (15 LOC)src-tauri/src/services/filler_detector.rs
fn test_confidence_calculation_with_duration() {
let word = TimedWord {
word: "um".to_string(),
start: 0.0,
end: 0.3, // Short duration
confidence: 0.9,
};
let filler_type = FillerType::Um;
let calculated_confidence = calculate_filler_confidence(&word, &filler_type, "um");
// Short duration = higher confidence
assert!(calculated_confidence > 0.8);
assert!(calculated_confidence <= 1.0);
}test_confidence_calculation_long_duration function · rust · L657-L670 (14 LOC)src-tauri/src/services/filler_detector.rs
fn test_confidence_calculation_long_duration() {
let word = TimedWord {
word: "um".to_string(),
start: 0.0,
end: 1.5, // Long duration for "um"
confidence: 0.9,
};
let filler_type = FillerType::Um;
let calculated_confidence = calculate_filler_confidence(&word, &filler_type, "um");
// Long duration = lower confidence factor
assert!(calculated_confidence < 0.9);
}test_overlapping_detection_merging function · rust · L673-L697 (25 LOC)src-tauri/src/services/filler_detector.rs
fn test_overlapping_detection_merging() {
let detections = vec![
FillerWordDetection {
start: 1.0,
end: 1.5,
word: "um".to_string(),
confidence: 0.9,
filler_type: FillerType::Um,
},
FillerWordDetection {
start: 1.4, // Overlapping (within 0.2s)
end: 2.0,
word: "uh".to_string(),
confidence: 0.85,
filler_type: FillerType::Uh,
},
];
let merged = merge_overlapping_detections(detections);
// Should merge into one detection
assert_eq!(merged.len(), 1);
assert_eq!(merged[0].start, 1.0);
assert_eq!(merged[0].end, 2.0);
}test_non_overlapping_detections function · rust · L700-L722 (23 LOC)src-tauri/src/services/filler_detector.rs
fn test_non_overlapping_detections() {
let detections = vec![
FillerWordDetection {
start: 1.0,
end: 1.5,
word: "um".to_string(),
confidence: 0.9,
filler_type: FillerType::Um,
},
FillerWordDetection {
start: 3.0, // Not overlapping (> 0.2s gap)
end: 3.5,
word: "uh".to_string(),
confidence: 0.85,
filler_type: FillerType::Uh,
},
];
let merged = merge_overlapping_detections(detections);
// Should NOT merge
assert_eq!(merged.len(), 2);
}Want this analysis on your repo? https://repobility.com/scan/
test_merge_empty_detections function · rust · L725-L729 (5 LOC)src-tauri/src/services/filler_detector.rs
fn test_merge_empty_detections() {
let detections: Vec<FillerWordDetection> = vec![];
let merged = merge_overlapping_detections(detections);
assert_eq!(merged.len(), 0);
}test_filler_type_as_str function · rust · L732-L739 (8 LOC)src-tauri/src/services/filler_detector.rs
fn test_filler_type_as_str() {
assert_eq!(FillerType::Um.as_str(), "um");
assert_eq!(FillerType::Uh.as_str(), "uh");
assert_eq!(FillerType::Like.as_str(), "like");
assert_eq!(FillerType::YouKnow.as_str(), "you know");
assert_eq!(FillerType::IMean.as_str(), "I mean");
assert_eq!(FillerType::Other("custom".to_string()).as_str(), "custom");
}test_word_clean function · rust · L742-L747 (6 LOC)src-tauri/src/services/filler_detector.rs
fn test_word_clean() {
assert_eq!(word_clean("um,"), "um");
assert_eq!(word_clean("uh!"), "uh");
assert_eq!(word_clean("like."), "like");
assert_eq!(word_clean("you?"), "you");
}test_config_default function · rust · L750-L755 (6 LOC)src-tauri/src/services/filler_detector.rs
fn test_config_default() {
let config = FillerDetectionConfig::default();
assert_eq!(config.min_confidence, 0.5);
assert!(config.use_phonetic);
assert!(config.custom_fillers.is_empty());
}test_find_filler_type function · rust · L758-L765 (8 LOC)src-tauri/src/services/filler_detector.rs
fn test_find_filler_type() {
assert!(matches!(find_filler_type("um"), FillerType::Um));
assert!(matches!(find_filler_type("uh"), FillerType::Uh));
assert!(matches!(find_filler_type("like"), FillerType::Like));
assert!(matches!(find_filler_type("you know"), FillerType::YouKnow));
assert!(matches!(find_filler_type("I mean"), FillerType::IMean));
assert!(matches!(find_filler_type("custom"), FillerType::Other(_)));
}test_phonetic_encoding_normalization function · rust · L768-L775 (8 LOC)src-tauri/src/services/filler_detector.rs
fn test_phonetic_encoding_normalization() {
// Test that phonetic encoding normalizes to 4 characters
let short = phonetic_encode("a");
assert_eq!(short.len(), 4);
let long = phonetic_encode("verylongword");
assert_eq!(long.len(), 4);
}test_phonetic_encoding_vowel_removal function · rust · L778-L786 (9 LOC)src-tauri/src/services/filler_detector.rs
fn test_phonetic_encoding_vowel_removal() {
// Vowels after first character should be removed
let encoded = phonetic_encode("audio");
assert_eq!(encoded.len(), 4); // Normalized to 4 chars
// First character is always kept
let encoded = phonetic_encode("eaio");
assert_eq!(encoded.chars().next(), Some('e'));
}test_timed_word_structure function · rust · L789-L802 (14 LOC)src-tauri/src/services/filler_detector.rs
fn test_timed_word_structure() {
let word = TimedWord {
word: "test".to_string(),
start: 1.0,
end: 1.5,
confidence: 0.95,
};
assert_eq!(word.word, "test");
assert_eq!(word.start, 1.0);
assert_eq!(word.end, 1.5);
assert_eq!(word.confidence, 0.95);
assert!(word.end > word.start);
}Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
test_transcription_structure function · rust · L805-L815 (11 LOC)src-tauri/src/services/filler_detector.rs
fn test_transcription_structure() {
let transcription = Transcription {
text: "test".to_string(),
words: vec![],
language: "en".to_string(),
};
assert_eq!(transcription.text, "test");
assert_eq!(transcription.language, "en");
assert!(transcription.words.is_empty());
}get_available_models function · rust · L42-L65 (24 LOC)src-tauri/src/services/model_manager.rs
pub fn get_available_models() -> Vec<ModelInfo> {
let active_model = get_active_model();
let models = vec![
WhisperModel::Tiny,
WhisperModel::Base,
WhisperModel::Small,
WhisperModel::Medium,
WhisperModel::Large,
];
models
.into_iter()
.map(|model| {
let is_downloaded = is_model_downloaded_impl(&model);
ModelInfo {
name: model.model_name().to_string(),
display_name: model.display_name().to_string(),
size_bytes: model.size_bytes(),
is_downloaded,
is_active: model == active_model,
}
})
.collect()
}is_model_downloaded_impl function · rust · L68-L73 (6 LOC)src-tauri/src/services/model_manager.rs
fn is_model_downloaded_impl(model: &WhisperModel) -> bool {
match get_model_path(*model) {
Ok(path) => path.exists(),
Err(_) => false,
}
}is_model_downloaded function · rust · L76-L81 (6 LOC)src-tauri/src/services/model_manager.rs
pub fn is_model_downloaded(model_name: &str) -> Result<bool, String> {
let model = WhisperModel::from_str(model_name)
.ok_or_else(|| format!("Invalid model name: {}", model_name))?;
Ok(is_model_downloaded_impl(&model))
}get_active_model function · rust · L84-L98 (15 LOC)src-tauri/src/services/model_manager.rs
pub fn get_active_model() -> WhisperModel {
// Try to read from settings file
if let Ok(models_dir) = get_models_dir() {
let settings_path = models_dir.join(ACTIVE_MODEL_FILE);
if let Ok(content) = fs::read_to_string(&settings_path) {
if let Some(model) = WhisperModel::from_str(content.trim()) {
return model;
}
}
}
// Default to Small model
WhisperModel::Small
}set_active_model function · rust · L101-L112 (12 LOC)src-tauri/src/services/model_manager.rs
pub fn set_active_model(model_name: &str) -> Result<(), String> {
let model = WhisperModel::from_str(model_name)
.ok_or_else(|| format!("Invalid model name: {}", model_name))?;
let models_dir = get_models_dir()?;
let settings_path = models_dir.join(ACTIVE_MODEL_FILE);
fs::write(&settings_path, model.model_name())
.map_err(|e| format!("Failed to write model settings: {}", e))?;
Ok(())
}delete_model function · rust · L115-L135 (21 LOC)src-tauri/src/services/model_manager.rs
pub fn delete_model(model_name: &str) -> Result<(), String> {
let model = WhisperModel::from_str(model_name)
.ok_or_else(|| format!("Invalid model name: {}", model_name))?;
// Don't allow deleting the active model
let active = get_active_model();
if model == active {
return Err("Cannot delete the active model. Please switch to a different model first.".to_string());
}
let model_path = get_model_path(model)?;
if !model_path.exists() {
return Err(format!("Model not found: {}", model_name));
}
fs::remove_file(&model_path)
.map_err(|e| format!("Failed to delete model: {}", e))?;
Ok(())
}download_model_async function · rust · L141-L481 (341 LOC)src-tauri/src/services/model_manager.rs
pub async fn download_model_async(
model_name: String,
app: tauri::AppHandle,
) -> Result<(), String> {
println!("[MODEL DOWNLOAD] Starting download for model: {}", model_name);
let model = WhisperModel::from_str(&model_name)
.ok_or_else(|| format!("Invalid model name: {}", model_name))?;
let model_path = get_model_path(model)?;
let expected_size = model.size_bytes();
println!("[MODEL DOWNLOAD] Model path: {:?}", model_path);
println!("[MODEL DOWNLOAD] Expected size: {} bytes", expected_size);
// Check if already downloaded
if model_path.exists() {
println!("[MODEL DOWNLOAD] Model already exists at path");
return Err("Model already downloaded".to_string());
}
// Ensure models directory exists
let models_dir = get_models_dir()?;
println!("[MODEL DOWNLOAD] Models directory: {:?}", models_dir);
let _ = std::fs::create_dir_all(&models_dir)
.map_err(|e| format!("Failed to create models directory:Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
verify_model_file function · rust · L242-L267 (26 LOC)src-tauri/src/services/model_manager.rs
fn verify_model_file(path: &Path, expected_size: u64) -> Result<(), String> {
// Check file exists
if !path.exists() {
return Err("Downloaded file not found".to_string());
}
// Check file size
let metadata = std::fs::metadata(path)
.map_err(|e| format!("Failed to read file metadata: {}", e))?;
let actual_size = metadata.len();
// Allow 5% variance in file size (actual HuggingFace sizes may vary)
let size_variance = (expected_size as f64 * 0.05) as u64;
let min_size = expected_size.saturating_sub(size_variance);
let max_size = expected_size.saturating_add(size_variance);
if actual_size < min_size || actual_size > max_size {
return Err(format!(
"File size mismatch: expected ~{} bytes, got {} bytes",
expected_size, actual_size
));
}
Ok(())
}new function · rust · L319-L326 (8 LOC)src-tauri/src/services/model_manager.rs
fn new(model_name: String, total_bytes: u64) -> Self {
Self {
last_emitted_percent: 0,
last_emit_time: std::time::Instant::now(),
model_name,
total_bytes,
}
}should_emit function · rust · L329-L354 (26 LOC)src-tauri/src/services/model_manager.rs
fn should_emit(&mut self, downloaded_bytes: u64) -> Option<ModelDownloadProgress> {
let percent = if self.total_bytes > 0 {
((downloaded_bytes as f64 / self.total_bytes as f64) * 100.0) as u8
} else {
0
};
let percent_change = percent.abs_diff(self.last_emitted_percent);
let time_elapsed = self.last_emit_time.elapsed();
// Emit if: 1% change OR 100ms elapsed
if percent_change >= 1 || time_elapsed.as_millis() >= 100 {
self.last_emitted_percent = percent;
self.last_emit_time = std::time::Instant::now();
Some(ModelDownloadProgress {
model: self.model_name.clone(),
progress: percent,
stage: DownloadStage::Downloading,
downloaded_bytes: Some(downloaded_bytes),
total_bytes: Some(self.total_bytes),
})
} else {
None
}
}final_progress function · rust · L357-L365 (9 LOC)src-tauri/src/services/model_manager.rs
fn final_progress(&self) -> ModelDownloadProgress {
ModelDownloadProgress {
model: self.model_name.clone(),
progress: 100,
stage: DownloadStage::Downloading,
downloaded_bytes: Some(self.total_bytes),
total_bytes: Some(self.total_bytes),
}
}download_model_file function · rust · L372-L470 (99 LOC)src-tauri/src/services/model_manager.rs
async fn download_model_file<F>(
url: &str,
dest_path: &Path,
model_name: String,
expected_size: u64,
mut progress_callback: F,
) -> Result<(), String>
where
F: FnMut(ModelDownloadProgress),
{
use reqwest::Client;
use futures_util::StreamExt;
use tokio::io::AsyncWriteExt;
println!("[MODEL DOWNLOAD] download_model_file: Starting download from {}", url);
// Create the parent directory if it doesn't exist
if let Some(parent) = dest_path.parent() {
tokio::fs::create_dir_all(parent)
.await
.map_err(|e| format!("Failed to create directory: {}", e))?;
}
// Create HTTP client
println!("[MODEL DOWNLOAD] Creating HTTP client...");
let client = Client::builder()
.build()
.map_err(|e| format!("Failed to create HTTP client: {}", e))?;
println!("[MODEL DOWNLOAD] HTTP client created");
// Start the download request
println!("[MODEL DOWNLOAD] Starting HTTP GET request...");
delete_model_async function · rust · L484-L491 (8 LOC)src-tauri/src/services/model_manager.rs
pub async fn delete_model_async(model_name: String) -> Result<(), String> {
// Run the blocking delete in a thread pool
tokio::task::spawn_blocking(move || {
delete_model(&model_name)
})
.await
.map_err(|e| format!("Failed to join task: {}", e))?
}test_get_available_models function · rust · L498-L508 (11 LOC)src-tauri/src/services/model_manager.rs
fn test_get_available_models() {
let models = get_available_models();
assert_eq!(models.len(), 5);
// Check that models are in correct order
assert_eq!(models[0].name, "tiny");
assert_eq!(models[1].name, "base");
assert_eq!(models[2].name, "small");
assert_eq!(models[3].name, "medium");
assert_eq!(models[4].name, "large");
}test_model_sizes function · rust · L511-L518 (8 LOC)src-tauri/src/services/model_manager.rs
fn test_model_sizes() {
let models = get_available_models();
// Verify sizes are in ascending order
for i in 1..models.len() {
assert!(models[i - 1].size_bytes < models[i].size_bytes);
}
}Repobility — the code-quality scanner for AI-generated software · https://repobility.com
test_get_active_model_default function · rust · L521-L524 (4 LOC)src-tauri/src/services/model_manager.rs
fn test_get_active_model_default() {
let active = get_active_model();
assert_eq!(active, WhisperModel::Small);
}test_set_active_model function · rust · L527-L534 (8 LOC)src-tauri/src/services/model_manager.rs
fn test_set_active_model() {
let temp_dir = std::env::temp_dir();
let test_models_dir = temp_dir.join("test-whisper-models");
// This would require mocking the dirs crate
// For now, we just verify the function signature
assert!(true);
}test_get_download_url function · rust · L537-L541 (5 LOC)src-tauri/src/services/model_manager.rs
fn test_get_download_url() {
let url = get_model_download_url("small").unwrap();
assert!(url.contains("ggml-small.bin"));
assert!(url.contains("huggingface.co"));
}