1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct Config {
18 #[serde(rename = "$schema", default = "default_schema")]
19 pub schema: String,
20
21 #[serde(default = "default_root_dir")]
22 pub root_dir: String,
23
24 #[serde(default)]
25 pub schemas: SchemasConfig,
26
27 #[serde(default)]
28 pub apis: ApisConfig,
29
30 #[serde(default)]
31 pub modules: ModulesConfig,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub spec_path: Option<String>,
35}
36
37pub fn default_schema() -> String {
38 "https://raw.githubusercontent.com/vikarno/vika-cli/main/schema/vika-config.schema.json"
39 .to_string()
40}
41
42fn default_root_dir() -> String {
43 "src".to_string()
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct SchemasConfig {
51 #[serde(default = "default_schemas_output")]
52 pub output: String,
53
54 #[serde(default = "default_naming")]
55 pub naming: String,
56}
57
58fn default_naming() -> String {
59 "PascalCase".to_string()
60}
61
62fn default_schemas_output() -> String {
63 "src/schemas".to_string()
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct ApisConfig {
71 #[serde(default = "default_apis_output")]
72 pub output: String,
73
74 #[serde(default = "default_style")]
75 pub style: String,
76
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub base_url: Option<String>,
79
80 #[serde(default = "default_header_strategy")]
81 pub header_strategy: String,
82}
83
84fn default_header_strategy() -> String {
85 "consumerInjected".to_string()
86}
87
88fn default_apis_output() -> String {
89 "src/apis".to_string()
90}
91
92fn default_style() -> String {
93 "fetch".to_string()
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize, Default)]
100pub struct ModulesConfig {
101 #[serde(default)]
102 pub ignore: Vec<String>,
103
104 #[serde(default)]
105 pub selected: Vec<String>,
106}
107
108impl Default for Config {
109 fn default() -> Self {
110 Self {
111 schema: default_schema(),
112 root_dir: default_root_dir(),
113 schemas: SchemasConfig {
114 output: default_schemas_output(),
115 naming: default_naming(),
116 },
117 apis: ApisConfig {
118 output: default_apis_output(),
119 style: default_style(),
120 base_url: None,
121 header_strategy: default_header_strategy(),
122 },
123 modules: ModulesConfig {
124 ignore: vec![],
125 selected: vec![],
126 },
127 spec_path: None,
128 }
129 }
130}
131
132impl Default for SchemasConfig {
133 fn default() -> Self {
134 Self {
135 output: default_schemas_output(),
136 naming: default_naming(),
137 }
138 }
139}
140
141impl Default for ApisConfig {
142 fn default() -> Self {
143 Self {
144 output: default_apis_output(),
145 style: default_style(),
146 base_url: None,
147 header_strategy: default_header_strategy(),
148 }
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155
156 #[test]
157 fn test_load_default_config() {
158 let config = Config::default();
159 assert_eq!(config.root_dir, "src");
160 assert_eq!(config.schemas.output, "src/schemas");
161 assert_eq!(config.apis.output, "src/apis");
162 assert_eq!(config.apis.style, "fetch");
163 assert!(!config.schema.is_empty());
164 }
165
166 #[test]
167 fn test_config_serialization() {
168 let config = Config::default();
169 let json = serde_json::to_string_pretty(&config).unwrap();
170
171 assert!(json.contains("\"root_dir\""));
172 assert!(json.contains("\"schemas\""));
173 assert!(json.contains("\"apis\""));
174 assert!(json.contains("\"$schema\""));
175 }
176
177 #[test]
178 fn test_config_deserialization() {
179 let json = r#"
180 {
181 "$schema": "https://example.com/schema.json",
182 "root_dir": "test",
183 "schemas": {
184 "output": "test/schemas",
185 "naming": "camelCase"
186 },
187 "apis": {
188 "output": "test/apis",
189 "style": "fetch",
190 "header_strategy": "bearerToken"
191 },
192 "modules": {
193 "ignore": ["test"],
194 "selected": []
195 }
196 }
197 "#;
198
199 let config: Config = serde_json::from_str(json).unwrap();
200 assert_eq!(config.root_dir, "test");
201 assert_eq!(config.schemas.output, "test/schemas");
202 assert_eq!(config.schemas.naming, "camelCase");
203 assert_eq!(config.apis.header_strategy, "bearerToken");
204 assert_eq!(config.modules.ignore, vec!["test"]);
205 }
206
207 #[test]
208 fn test_config_with_base_url() {
209 let mut config = Config::default();
210 config.apis.base_url = Some("/api/v1".to_string());
211
212 let json = serde_json::to_string_pretty(&config).unwrap();
213 assert!(json.contains("\"base_url\""));
214 assert!(json.contains("/api/v1"));
215 }
216
217 #[test]
218 fn test_config_schema_field() {
219 let config = Config::default();
220 let json = serde_json::to_string_pretty(&config).unwrap();
221
222 assert!(json.contains("\"$schema\""));
224 }
225}