tauri_plugin_stt/
paths.rs1use std::fs::create_dir_all;
5use std::path::PathBuf;
6use tauri::{AppHandle, Manager, Runtime};
7
8use crate::error::Error;
9
10const MODELS_SUBDIR: &str = "whisper-models";
12
13#[allow(dead_code)]
24pub fn get_models_dir<R: Runtime>(app: &AppHandle<R>) -> Result<PathBuf, Error> {
25 let base_path = app
26 .path()
27 .app_data_dir()
28 .map_err(|e| Error::ConfigError(format!("Could not determine app data directory: {e}")))?;
29
30 let full_path = base_path.join(MODELS_SUBDIR);
31
32 create_dir_all(&full_path).map_err(|e| {
33 Error::ConfigError(format!(
34 "Could not create models directory {}: {}",
35 full_path.display(),
36 e
37 ))
38 })?;
39
40 Ok(full_path)
41}
42
43#[allow(dead_code)]
49pub fn get_model_path<R: Runtime>(app: &AppHandle<R>, model_name: &str) -> Result<PathBuf, Error> {
50 validate_path(model_name)?;
51 let models_dir = get_models_dir(app)?;
52 Ok(models_dir.join(model_name))
53}
54
55#[allow(dead_code)]
57pub fn model_exists<R: Runtime>(app: &AppHandle<R>, model_name: &str) -> Result<bool, Error> {
58 let model_path = get_model_path(app, model_name)?;
59 Ok(model_path.exists() && model_path.is_file())
61}
62
63#[allow(dead_code)]
67pub fn list_available_models<R: Runtime>(app: &AppHandle<R>) -> Result<Vec<String>, Error> {
68 let models_dir = get_models_dir(app)?;
69 let mut models = Vec::new();
70
71 if let Ok(entries) = std::fs::read_dir(&models_dir) {
72 for entry in entries.flatten() {
73 if let Ok(metadata) = entry.metadata() {
74 if metadata.is_file() {
76 if let Some(name) = entry.file_name().to_str() {
77 if name.ends_with(".bin") {
78 models.push(name.to_string());
79 }
80 }
81 }
82 }
83 }
84 }
85
86 Ok(models)
87}
88
89#[allow(dead_code)]
91pub fn validate_path(path: &str) -> Result<(), Error> {
92 let path_buf = PathBuf::from(path);
93
94 for component in path_buf.components() {
95 if let std::path::Component::ParentDir = component {
96 return Err(Error::ConfigError(
97 "Path traversal not allowed (contains '..')".to_string(),
98 ));
99 }
100 }
101
102 Ok(())
103}