rew_core/
utils.rs

1pub use crate::{AppConfig, AppInfo, AppManifest};
2// use serde::{Deserialize, Serialize};
3use std::env;
4use std::fs;
5use std::path::{Path, PathBuf};
6
7// Get the Rew root directory
8pub fn get_rew_root() -> PathBuf {
9  // First check for REW_ROOT environment variable
10  if let Ok(rew_root) = env::var("REW_ROOT") {
11    return PathBuf::from(rew_root);
12  }
13
14  // Otherwise use the default location based on platform
15  #[cfg(target_os = "windows")]
16  {
17    let local_app_data = env::var("LOCALAPPDATA").unwrap_or_else(|_| {
18      let home = env::var("USERPROFILE").unwrap_or_else(|_| ".".to_string());
19      format!("{}\\AppData\\Local", home)
20    });
21    PathBuf::from(format!("{}\\rew", local_app_data))
22  }
23
24  #[cfg(not(target_os = "windows"))]
25  {
26    if std::path::Path::new("/opt/rew").exists() {
27      PathBuf::from("/opt/rew")
28    } else {
29      let home = env::var("HOME").unwrap_or_else(|_| ".".to_string());
30      PathBuf::from(format!("{}/.rew", home))
31    }
32  }
33}
34
35// Find an app by package name
36pub fn find_app_by_package(package_name: &str) -> Option<AppInfo> {
37  let rew_root = get_rew_root();
38  let apps_dir = rew_root.join("apps");
39
40  if !apps_dir.exists() {
41    return None;
42  }
43
44  let app_dirs = fs::read_dir(&apps_dir).ok()?;
45
46  for dir_entry in app_dirs.flatten() {
47    let app_dir = dir_entry.path();
48    if !app_dir.is_dir() {
49      continue;
50    }
51
52    let config_path = app_dir.join("app.yaml");
53    if !config_path.exists() {
54      continue;
55    }
56
57    // Read and parse the app.yaml file
58    let config_str = fs::read_to_string(&config_path).ok()?;
59    let config: AppConfig = serde_yaml::from_str(&config_str).ok()?;
60
61    // Check if this app has the requested package name
62    if let Some(manifest) = &config.manifest {
63      if let Some(pkg) = &manifest.package {
64        if pkg == package_name {
65          return Some(AppInfo {
66            path: app_dir,
67            config,
68          });
69        }
70      }
71    }
72  }
73
74  None
75}
76
77// Find app info for a file path
78pub fn find_app_info(file_path: &Path) -> Option<AppInfo> {
79  let mut current = file_path;
80
81  // Walk up the directory tree looking for app.yaml
82  while let Some(parent) = current.parent() {
83    let config_path = parent.join("app.yaml");
84    if config_path.exists() {
85      // Found an app.yaml, parse it
86      let config_str = fs::read_to_string(&config_path).ok()?;
87      let config: AppConfig = serde_yaml::from_str(&config_str).ok()?;
88
89      return Some(AppInfo {
90        path: parent.to_path_buf(),
91        config,
92      });
93    }
94    current = parent;
95  }
96
97  None
98}
99
100// Resolve an app entry point
101pub fn resolve_app_entry(package_name: &str, entry_name: Option<&str>) -> Option<PathBuf> {
102  let app_info = find_app_by_package(package_name)?;
103
104  // Get the entries from the config
105  let entries = app_info.config.entries.as_ref()?;
106
107  // Determine which entry to use
108  let entry_key = entry_name.unwrap_or("main");
109  let entry_path = entries.get(entry_key)?;
110
111  // Resolve the entry path relative to the app directory
112  Some(app_info.path.join(entry_path))
113}
114
115// Find the app path for a given file
116pub fn find_app_path(dir_path: &Path) -> Option<PathBuf> {
117  let mut current = dir_path;
118
119  // Walk up the directory tree looking for app.yaml
120  while let Some(parent) = current.parent() {
121    let config_path = parent.join("app.yaml");
122    if config_path.exists() {
123      return Some(parent.to_path_buf());
124    }
125    current = parent;
126  }
127
128  None
129}
130
131#[allow(unused)]
132pub fn is_valid_utf8<P: AsRef<Path>>(path: P) -> std::io::Result<bool> {
133  let bytes = std::fs::read(path)?;
134  Ok(std::str::from_utf8(&bytes).is_ok())
135}