vika_cli/templates/
resolver.rs1use crate::error::Result;
2use crate::templates::loader::TemplateLoader;
3use crate::templates::registry::TemplateId;
4use std::path::Path;
5
6pub struct TemplateResolver {
8 project_root: Option<std::path::PathBuf>,
9}
10
11impl TemplateResolver {
12 pub fn new(project_root: Option<&Path>) -> Self {
14 Self {
15 project_root: project_root.map(|p| p.to_path_buf()),
16 }
17 }
18
19 pub fn resolve(&self, template_id: TemplateId) -> Result<String> {
21 let template_name = template_id.name();
22
23 if let Some(ref project_root) = self.project_root {
25 if let Some(user_template) = TemplateLoader::load_user(template_name, project_root)? {
26 return Ok(user_template);
27 }
28 }
29
30 TemplateLoader::load_builtin(template_name)
32 }
33
34 pub fn is_overridden(&self, template_id: TemplateId) -> bool {
36 if let Some(ref project_root) = self.project_root {
37 let template_name = template_id.name();
38 let user_template_dir = project_root.join(".vika").join("templates");
39 let template_path = user_template_dir.join(format!("{}.tera", template_name));
40 template_path.exists()
41 } else {
42 false
43 }
44 }
45
46 pub fn list_templates(&self) -> Result<Vec<(String, bool)>> {
48 let builtin = TemplateLoader::list_builtin();
49 let user = if let Some(ref project_root) = self.project_root {
50 TemplateLoader::list_user(project_root)?
51 } else {
52 Vec::new()
53 };
54
55 let mut result: Vec<(String, bool)> = builtin
56 .iter()
57 .map(|name| {
58 let overridden = user.contains(name);
59 (name.clone(), overridden)
60 })
61 .collect();
62
63 for name in user {
65 if !result.iter().any(|(n, _)| n == &name) {
66 result.push((name, true));
67 }
68 }
69
70 Ok(result)
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use tempfile::TempDir;
78
79 #[test]
80 fn test_resolve_builtin() {
81 let resolver = TemplateResolver::new(None);
82 let result = resolver.resolve(TemplateId::TypeInterface);
83 assert!(result.is_ok());
84 }
85
86 #[test]
87 fn test_is_overridden_false() {
88 let temp_dir = TempDir::new().unwrap();
89 let resolver = TemplateResolver::new(Some(temp_dir.path()));
90 assert!(!resolver.is_overridden(TemplateId::TypeInterface));
91 }
92
93 #[test]
94 fn test_list_templates() {
95 let resolver = TemplateResolver::new(None);
96 let templates = resolver.list_templates().unwrap();
97 assert!(!templates.is_empty());
98 }
99}