ggen_cli_lib/cmds/
template.rs1use clap_noun_verb::Result as NounVerbResult;
6use clap_noun_verb_macros::verb;
7use serde::Serialize;
8use std::path::PathBuf;
9
10#[derive(Serialize)]
15struct ShowOutput {
16 name: String,
17 path: String,
18 description: Option<String>,
19 output_path: Option<String>,
20 variables: Vec<String>,
21 rdf_sources: Vec<String>,
22 sparql_queries_count: usize,
23 determinism_seed: Option<u64>,
24}
25
26#[derive(Serialize)]
27struct NewOutput {
28 template_name: String,
29 template_type: String,
30 path: String,
31}
32
33#[derive(Serialize)]
34struct ListOutput {
35 templates: Vec<TemplateInfo>,
36 total: usize,
37 directory: String,
38}
39
40#[derive(Serialize)]
41struct TemplateInfo {
42 name: String,
43 source: String,
44 description: Option<String>,
45 path: String,
46}
47
48#[derive(Serialize)]
49struct LintOutput {
50 has_errors: bool,
51 has_warnings: bool,
52 errors: Vec<LintMessage>,
53 warnings: Vec<LintMessage>,
54}
55
56#[derive(Serialize)]
57struct LintMessage {
58 line: Option<usize>,
59 message: String,
60}
61
62#[verb]
68fn show(template: String) -> NounVerbResult<ShowOutput> {
69 use ggen_core::domain::template::show;
70
71 let metadata = show::show_template_metadata(&template).map_err(|e| {
72 clap_noun_verb::NounVerbError::execution_error(format!("Failed to show template: {}", e))
73 })?;
74
75 Ok(ShowOutput {
76 name: metadata.name,
77 path: metadata.path,
78 description: metadata.description,
79 output_path: metadata.output_path,
80 variables: metadata.variables,
81 rdf_sources: metadata.rdf_sources,
82 sparql_queries_count: metadata.sparql_queries.len(),
83 determinism_seed: metadata.determinism_seed,
84 })
85}
86
87#[verb]
89fn new(name: String, template_type: Option<String>) -> NounVerbResult<NewOutput> {
90 use ggen_core::domain::template::new as template_new;
91 use ggen_core::domain::template::TemplateService;
92
93 let template_type_str = template_type.as_deref().unwrap_or("generic");
94
95 let content =
96 template_new::generate_template_content(&name, template_type_str).map_err(|e| {
97 clap_noun_verb::NounVerbError::execution_error(format!(
98 "Failed to generate template: {}",
99 e
100 ))
101 })?;
102
103 let service = TemplateService::default_instance();
104 let path = service.write_template(&name, &content).map_err(|e| {
105 clap_noun_verb::NounVerbError::execution_error(format!("Failed to write template: {}", e))
106 })?;
107
108 Ok(NewOutput {
109 template_name: name,
110 template_type: template_type_str.to_string(),
111 path: path.display().to_string(),
112 })
113}
114
115#[verb]
117fn list(directory: Option<PathBuf>) -> NounVerbResult<ListOutput> {
118 use ggen_core::domain::template::list;
119
120 let default_dir = PathBuf::from("templates");
121 let templates_dir = directory.as_ref().unwrap_or(&default_dir);
122
123 let filters = list::ListFilters {
124 pattern: None,
125 local_only: false,
126 gpack_only: false,
127 };
128
129 let templates = list::list_templates(templates_dir, &filters).map_err(|e| {
130 clap_noun_verb::NounVerbError::execution_error(format!("Failed to list templates: {}", e))
131 })?;
132
133 let template_infos = templates
134 .into_iter()
135 .map(|t| TemplateInfo {
136 name: t.name,
137 source: match t.source {
138 list::TemplateSource::Local => "local".to_string(),
139 list::TemplateSource::Gpack(name) => name,
140 },
141 description: t.description,
142 path: t.path,
143 })
144 .collect::<Vec<_>>();
145
146 let total = template_infos.len();
147
148 Ok(ListOutput {
149 templates: template_infos,
150 total,
151 directory: templates_dir.display().to_string(),
152 })
153}
154
155#[verb]
157fn lint(template: String) -> NounVerbResult<LintOutput> {
158 use ggen_core::domain::template::lint;
159
160 let options = lint::LintOptions {
161 check_sparql: false,
162 check_schema: false,
163 };
164
165 let report = lint::lint_template(&template, &options).map_err(|e| {
166 clap_noun_verb::NounVerbError::execution_error(format!("Failed to lint template: {}", e))
167 })?;
168
169 let has_errors = report.has_errors();
170 let has_warnings = report.has_warnings();
171
172 let errors = report
173 .errors
174 .into_iter()
175 .map(|e| LintMessage {
176 line: e.line,
177 message: e.message,
178 })
179 .collect();
180
181 let warnings = report
182 .warnings
183 .into_iter()
184 .map(|w| LintMessage {
185 line: w.line,
186 message: w.message,
187 })
188 .collect();
189
190 Ok(LintOutput {
191 has_errors,
192 has_warnings,
193 errors,
194 warnings,
195 })
196}
197
198