lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

service.rs (3139B)


      1 use std::path::{Path, PathBuf};
      2 
      3 use crate::{InstanceId, ServiceId, roots::RadrootsPaths};
      4 
      5 /// Canonical directories owned by one validated service instance.
      6 ///
      7 /// Callers cannot construct this value without the crate's validated identity
      8 /// and root derivation boundary.
      9 ///
     10 /// ```compile_fail
     11 /// use std::path::PathBuf;
     12 /// use radroots_runtime_paths::RadrootsServiceInstancePaths;
     13 ///
     14 /// let _forged = RadrootsServiceInstancePaths {
     15 ///     config: PathBuf::from("/tmp/escape"),
     16 ///     state: PathBuf::from("/tmp/escape"),
     17 ///     cache: PathBuf::from("/tmp/escape"),
     18 ///     logs: PathBuf::from("/tmp/escape"),
     19 ///     run: PathBuf::from("/tmp/escape"),
     20 ///     secrets: PathBuf::from("/tmp/escape"),
     21 /// };
     22 /// ```
     23 #[derive(Debug, Clone, PartialEq, Eq)]
     24 pub struct RadrootsServiceInstancePaths {
     25     state_root: PathBuf,
     26     config: PathBuf,
     27     state: PathBuf,
     28     cache: PathBuf,
     29     logs: PathBuf,
     30     run: PathBuf,
     31     secrets: PathBuf,
     32 }
     33 
     34 impl RadrootsServiceInstancePaths {
     35     pub(crate) fn from_resolved_roots(
     36         roots: &RadrootsPaths,
     37         service: &ServiceId,
     38         instance: &InstanceId,
     39     ) -> Self {
     40         let relative = Path::new("services")
     41             .join(service.as_str())
     42             .join(instance.as_str());
     43         Self {
     44             state_root: roots.data.clone(),
     45             config: roots.config.join(&relative),
     46             state: roots.data.join(&relative),
     47             cache: roots.cache.join(&relative),
     48             logs: roots.logs.join(&relative),
     49             run: roots.run.join(&relative),
     50             secrets: roots.secrets.join(relative),
     51         }
     52     }
     53 
     54     #[must_use]
     55     pub fn config(&self) -> &Path {
     56         &self.config
     57     }
     58 
     59     #[must_use]
     60     pub fn state(&self) -> &Path {
     61         &self.state
     62     }
     63 
     64     #[must_use]
     65     pub fn cache(&self) -> &Path {
     66         &self.cache
     67     }
     68 
     69     #[must_use]
     70     pub fn logs(&self) -> &Path {
     71         &self.logs
     72     }
     73 
     74     #[must_use]
     75     pub fn run(&self) -> &Path {
     76         &self.run
     77     }
     78 
     79     #[must_use]
     80     pub fn secrets(&self) -> &Path {
     81         &self.secrets
     82     }
     83 
     84     pub(crate) fn state_root(&self) -> &Path {
     85         &self.state_root
     86     }
     87 }
     88 
     89 #[cfg(test)]
     90 mod tests {
     91     use std::path::PathBuf;
     92 
     93     use super::RadrootsServiceInstancePaths;
     94     use crate::{InstanceId, ServiceId, roots::RadrootsPaths};
     95 
     96     #[test]
     97     fn canonical_service_instance_suffix_uses_validated_ids() {
     98         let roots = RadrootsPaths::from_base_root("/repo/.local/radroots");
     99         let paths = RadrootsServiceInstancePaths::from_resolved_roots(
    100             &roots,
    101             &ServiceId::new("myc").expect("service"),
    102             &InstanceId::new("primary").expect("instance"),
    103         );
    104         let suffix = PathBuf::from("services/myc/primary");
    105 
    106         assert_eq!(paths.config(), roots.config.join(&suffix));
    107         assert_eq!(paths.state(), roots.data.join(&suffix));
    108         assert_eq!(paths.cache(), roots.cache.join(&suffix));
    109         assert_eq!(paths.logs(), roots.logs.join(&suffix));
    110         assert_eq!(paths.run(), roots.run.join(&suffix));
    111         assert_eq!(paths.secrets(), roots.secrets.join(&suffix));
    112     }
    113 }