Skip to main content

systemprompt_cli/commands/web/
paths.rs

1use anyhow::{Context, Result};
2use std::fs;
3use std::path::{Path, PathBuf};
4use systemprompt_models::profile_bootstrap::ProfileBootstrap;
5use systemprompt_models::validators::WebConfigRaw;
6use systemprompt_models::Profile;
7
8const DEFAULT_TEMPLATES_PATH: &str = "web/templates";
9const DEFAULT_ASSETS_PATH: &str = "web/assets";
10
11#[derive(Debug)]
12pub struct WebPaths {
13    pub templates: PathBuf,
14    pub assets: PathBuf,
15}
16
17impl WebPaths {
18    pub fn resolve() -> Result<Self> {
19        let profile = ProfileBootstrap::get().context("Failed to get profile")?;
20        Self::resolve_from_profile(profile)
21    }
22
23    pub fn resolve_from_profile(profile: &Profile) -> Result<Self> {
24        let web_config_path = profile.paths.web_config();
25        let services_path = &profile.paths.services;
26
27        let (templates_path, assets_path) = match fs::read_to_string(&web_config_path) {
28            Ok(content) => {
29                let web_config: WebConfigRaw =
30                    serde_yaml::from_str(&content).with_context(|| {
31                        format!("Failed to parse web config at {}", web_config_path)
32                    })?;
33
34                match web_config.paths {
35                    Some(paths) => (
36                        paths
37                            .templates
38                            .unwrap_or_else(|| DEFAULT_TEMPLATES_PATH.to_string()),
39                        paths
40                            .assets
41                            .unwrap_or_else(|| DEFAULT_ASSETS_PATH.to_string()),
42                    ),
43                    None => (
44                        DEFAULT_TEMPLATES_PATH.to_string(),
45                        DEFAULT_ASSETS_PATH.to_string(),
46                    ),
47                }
48            },
49            Err(e) if e.kind() == std::io::ErrorKind::NotFound => (
50                DEFAULT_TEMPLATES_PATH.to_string(),
51                DEFAULT_ASSETS_PATH.to_string(),
52            ),
53            Err(e) => {
54                return Err(e)
55                    .with_context(|| format!("Failed to read web config at {}", web_config_path));
56            },
57        };
58
59        let base = Path::new(services_path);
60
61        let templates = if Path::new(&templates_path).is_absolute() {
62            PathBuf::from(&templates_path)
63        } else {
64            base.join(&templates_path)
65        };
66
67        let assets = if Path::new(&assets_path).is_absolute() {
68            PathBuf::from(&assets_path)
69        } else {
70            base.join(&assets_path)
71        };
72
73        Ok(Self { templates, assets })
74    }
75}