Skip to main content

systemprompt_models/paths/
system.rs

1//! System path resolution with canonicalisation and defaults discovery.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use std::path::{Path, PathBuf};
7
8use super::PathError;
9use crate::profile::PathsConfig;
10
11#[derive(Debug, Clone)]
12pub struct SystemPaths {
13    root: PathBuf,
14    services: PathBuf,
15    skills: PathBuf,
16    settings: PathBuf,
17    content_config: PathBuf,
18    geoip_database: Option<PathBuf>,
19    defaults: PathBuf,
20}
21
22impl SystemPaths {
23    const LOGS_DIR: &'static str = "logs";
24
25    pub fn from_profile(paths: &PathsConfig) -> Result<Self, PathError> {
26        let root = Self::canonicalize(&paths.system, "system")?;
27        let defaults = Self::resolve_defaults_dir(&root);
28
29        Ok(Self {
30            root,
31            services: PathBuf::from(&paths.services),
32            skills: PathBuf::from(paths.skills()),
33            settings: PathBuf::from(paths.config()),
34            content_config: PathBuf::from(paths.content_config()),
35            geoip_database: paths.geoip_database.as_ref().map(PathBuf::from),
36            defaults,
37        })
38    }
39
40    fn canonicalize(path: &str, field: &'static str) -> Result<PathBuf, PathError> {
41        std::fs::canonicalize(path).map_err(|source| PathError::CanonicalizeFailed {
42            path: PathBuf::from(path),
43            field,
44            source,
45        })
46    }
47
48    fn resolve_defaults_dir(root: &Path) -> PathBuf {
49        root.join("defaults")
50    }
51
52    pub fn root(&self) -> &Path {
53        &self.root
54    }
55
56    pub fn services(&self) -> &Path {
57        &self.services
58    }
59
60    pub fn skills(&self) -> &Path {
61        &self.skills
62    }
63
64    pub fn settings(&self) -> &Path {
65        &self.settings
66    }
67
68    pub fn content_config(&self) -> &Path {
69        &self.content_config
70    }
71
72    pub fn geoip_database(&self) -> Option<&Path> {
73        self.geoip_database.as_deref()
74    }
75
76    pub fn logs(&self) -> PathBuf {
77        self.root.join(Self::LOGS_DIR)
78    }
79
80    pub fn defaults(&self) -> &Path {
81        &self.defaults
82    }
83}