Skip to main content

telar_services_core/
paths.rs

1use std::path::PathBuf;
2
3pub trait AppPathsProvider: Send + Sync {
4    fn config_dir(&self) -> Option<PathBuf>;
5    fn data_dir(&self) -> Option<PathBuf>;
6    fn cache_dir(&self) -> Option<PathBuf>;
7
8    /// OS system-font directory to scan for fallback family resolution. `None` on platforms where the
9    /// renderer's default font discovery suffices (desktop); the platform adapter overrides it where the OS
10    /// keeps fonts in a fixed location (Android → `/system/fonts`).
11    fn system_fonts_dir(&self) -> Option<PathBuf> {
12        None
13    }
14    /// Sans-serif family names to try in priority order, OS/OEM-specific. Empty when default discovery
15    /// suffices; the platform adapter overrides it (Android OEM font stacks).
16    fn sans_serif_candidates(&self) -> Vec<String> {
17        Vec::new()
18    }
19}
20
21/// A provider that reports no directories at all, so nothing it is handed to touches a real XDG path.
22///
23/// Public rather than test-only: a preview window, a headless rasterise and every integration test want the
24/// same answer, and each had written its own copy of these three `None`s.
25pub struct NoPaths;
26
27impl AppPathsProvider for NoPaths {
28    fn config_dir(&self) -> Option<PathBuf> {
29        None
30    }
31
32    fn data_dir(&self) -> Option<PathBuf> {
33        None
34    }
35
36    fn cache_dir(&self) -> Option<PathBuf> {
37        None
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    struct MockPathsProvider {
46        config: PathBuf,
47        data: PathBuf,
48        cache: PathBuf,
49    }
50
51    impl AppPathsProvider for MockPathsProvider {
52        fn config_dir(&self) -> Option<PathBuf> {
53            Some(self.config.clone())
54        }
55
56        fn data_dir(&self) -> Option<PathBuf> {
57            Some(self.data.clone())
58        }
59
60        fn cache_dir(&self) -> Option<PathBuf> {
61            Some(self.cache.clone())
62        }
63    }
64
65    #[test]
66    fn test_mock_provider_config_dir() {
67        let provider = MockPathsProvider {
68            config: PathBuf::from("/mock/config"),
69            data: PathBuf::from("/mock/data"),
70            cache: PathBuf::from("/mock/cache"),
71        };
72
73        assert_eq!(provider.config_dir(), Some(PathBuf::from("/mock/config")));
74    }
75
76    #[test]
77    fn test_mock_provider_data_dir() {
78        let provider = MockPathsProvider {
79            config: PathBuf::from("/mock/config"),
80            data: PathBuf::from("/mock/data"),
81            cache: PathBuf::from("/mock/cache"),
82        };
83
84        assert_eq!(provider.data_dir(), Some(PathBuf::from("/mock/data")));
85    }
86
87    #[test]
88    fn test_mock_provider_cache_dir() {
89        let provider = MockPathsProvider {
90            config: PathBuf::from("/mock/config"),
91            data: PathBuf::from("/mock/data"),
92            cache: PathBuf::from("/mock/cache"),
93        };
94
95        assert_eq!(provider.cache_dir(), Some(PathBuf::from("/mock/cache")));
96    }
97
98    #[test]
99    fn test_none_provider_handles_missing_paths() {
100        let provider = NoPaths;
101
102        assert_eq!(provider.config_dir(), None);
103        assert_eq!(provider.data_dir(), None);
104        assert_eq!(provider.cache_dir(), None);
105    }
106}