1use schemars::JsonSchema;
4use serde::Deserialize;
5use serde::de::IgnoredAny;
6
7use super::de::{Located, Loose, Map, OneOf, Text, UnknownKeys};
8
9type JsonMap = serde_json::Map<String, serde_json::Value>;
10
11#[derive(Deserialize, JsonSchema)]
13#[schemars(title = "DRE sources", deny_unknown_fields)]
14pub struct SourcesFile {
15 #[schemars(required)]
17 pub sources: Option<Located<Loose<Option<Vec<SourceItem>>>>>,
18 #[serde(default)]
20 #[schemars(schema_with = "anything")]
21 pub version: Option<IgnoredAny>,
22}
23
24pub type SourceItem = Located<Loose<Source>>;
26pub type TableItem = Located<Loose<Table>>;
28
29type Dbt = Option<IgnoredAny>;
31
32#[derive(Deserialize, JsonSchema)]
34#[schemars(rename = "source", deny_unknown_fields)]
35pub struct Source {
36 #[schemars(required, with = "String")]
38 pub name: Option<Loose<String>>,
39 pub description: Option<Loose<Text>>,
41 pub database: Option<Loose<Text>>,
43 pub schema: Option<Loose<Text>>,
45 pub profile: Option<Loose<Text>>,
47 pub quoting: Option<Loose<Quoting>>,
48 pub tags: Option<Loose<Tags>>,
49 pub meta: Option<Loose<Meta>>,
50 pub tables: Option<Loose<Option<Vec<TableItem>>>>,
52 #[serde(default)]
54 #[schemars(schema_with = "anything")]
55 pub loader: Dbt,
56 #[serde(default)]
58 #[schemars(schema_with = "anything")]
59 pub loaded_at_field: Dbt,
60 #[serde(default)]
62 #[schemars(schema_with = "anything")]
63 pub loaded_at_query: Dbt,
64 #[serde(default)]
66 #[schemars(schema_with = "anything")]
67 pub config: Dbt,
68 #[serde(default)]
70 #[schemars(schema_with = "anything")]
71 pub overrides: Dbt,
72 #[serde(default)]
74 #[schemars(schema_with = "anything")]
75 pub freshness: Dbt,
76 #[serde(default)]
78 #[schemars(schema_with = "anything")]
79 pub docs: Dbt,
80 #[serde(rename = "$unknown", default)]
81 #[schemars(skip)]
82 pub unknown: UnknownKeys,
83}
84
85#[derive(Deserialize, JsonSchema)]
87#[schemars(rename = "table", deny_unknown_fields)]
88pub struct Table {
89 #[schemars(required, with = "String")]
91 pub name: Option<Loose<String>>,
92 pub identifier: Option<Loose<Text>>,
94 pub description: Option<Loose<Text>>,
96 pub quoting: Option<Loose<Quoting>>,
97 pub tags: Option<Loose<Tags>>,
98 pub meta: Option<Loose<Meta>>,
99 pub columns: Option<Loose<Option<Vec<Loose<Column>>>>>,
101 #[serde(default)]
103 #[schemars(schema_with = "anything")]
104 pub loaded_at_field: Dbt,
105 #[serde(default)]
107 #[schemars(schema_with = "anything")]
108 pub loaded_at_query: Dbt,
109 #[serde(default)]
111 #[schemars(schema_with = "anything")]
112 pub tests: Dbt,
113 #[serde(default)]
115 #[schemars(schema_with = "anything")]
116 pub data_tests: Dbt,
117 #[serde(default)]
119 #[schemars(schema_with = "anything")]
120 pub freshness: Dbt,
121 #[serde(default)]
123 #[schemars(schema_with = "anything")]
124 pub external: Dbt,
125 #[serde(default)]
127 #[schemars(schema_with = "anything")]
128 pub config: Dbt,
129 #[serde(default)]
131 #[schemars(schema_with = "anything")]
132 pub docs: Dbt,
133 #[serde(rename = "$unknown", default)]
134 #[schemars(skip)]
135 pub unknown: UnknownKeys,
136}
137
138#[derive(Deserialize, JsonSchema)]
140#[schemars(rename = "column", deny_unknown_fields)]
141pub struct Column {
142 #[schemars(required, with = "String")]
144 pub name: Option<Loose<String>>,
145 pub description: Option<Loose<Text>>,
147 pub data_type: Option<Loose<Text>>,
149 #[serde(default)]
151 #[schemars(schema_with = "anything")]
152 pub meta: Dbt,
153 #[serde(default)]
155 #[schemars(schema_with = "anything")]
156 pub tags: Dbt,
157 #[serde(default)]
159 #[schemars(schema_with = "anything")]
160 pub quote: Dbt,
161 #[serde(default)]
163 #[schemars(schema_with = "anything")]
164 pub tests: Dbt,
165 #[serde(default)]
167 #[schemars(schema_with = "anything")]
168 pub data_tests: Dbt,
169 #[serde(default)]
171 #[schemars(schema_with = "anything")]
172 pub constraints: Dbt,
173 #[serde(default)]
175 #[schemars(schema_with = "anything")]
176 pub config: Dbt,
177 #[serde(default)]
179 #[schemars(schema_with = "anything")]
180 pub docs: Dbt,
181 #[serde(default)]
183 #[schemars(schema_with = "anything")]
184 pub granularity: Dbt,
185 #[serde(rename = "$unknown", default)]
186 #[schemars(skip)]
187 pub unknown: UnknownKeys,
188}
189
190#[derive(Deserialize, JsonSchema)]
192#[schemars(rename = "quoting", deny_unknown_fields)]
193pub struct Quoting {
194 #[serde(default)]
196 #[schemars(with = "bool")]
197 pub database: Option<Loose<bool>>,
198 #[serde(default)]
200 #[schemars(with = "bool")]
201 pub schema: Option<Loose<bool>>,
202 #[serde(default)]
204 #[schemars(with = "bool")]
205 pub identifier: Option<Loose<bool>>,
206 #[serde(rename = "$unknown", default)]
207 #[schemars(skip)]
208 pub unknown: Map<serde_json::Value>,
209}
210
211#[derive(Deserialize, JsonSchema)]
213#[serde(transparent)]
214#[schemars(rename = "tags")]
215pub struct Tags(pub OneOf<String, Vec<String>>);
216
217#[derive(Deserialize, JsonSchema)]
219#[serde(transparent)]
220#[schemars(rename = "meta")]
221pub struct Meta(#[schemars(schema_with = "any_map")] pub JsonMap);
222
223fn anything(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
224 schemars::json_schema!({})
225}
226
227fn any_map(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
228 schemars::json_schema!({"type": "object", "additionalProperties": true})
229}
230
231impl Source {
232 pub fn dbt_keys(&self) -> Vec<&'static str> {
234 [
235 ("loader", &self.loader),
236 ("loaded_at_field", &self.loaded_at_field),
237 ("loaded_at_query", &self.loaded_at_query),
238 ("config", &self.config),
239 ("overrides", &self.overrides),
240 ("freshness", &self.freshness),
241 ("docs", &self.docs),
242 ]
243 .into_iter()
244 .filter_map(|(k, v)| v.is_some().then_some(k))
245 .collect()
246 }
247}
248
249impl Table {
250 pub fn dbt_keys(&self) -> Vec<&'static str> {
252 [
253 ("loaded_at_field", &self.loaded_at_field),
254 ("loaded_at_query", &self.loaded_at_query),
255 ("tests", &self.tests),
256 ("data_tests", &self.data_tests),
257 ("freshness", &self.freshness),
258 ("external", &self.external),
259 ("config", &self.config),
260 ("docs", &self.docs),
261 ]
262 .into_iter()
263 .filter_map(|(k, v)| v.is_some().then_some(k))
264 .collect()
265 }
266}
267
268impl Column {
269 pub fn dbt_keys(&self) -> Vec<&'static str> {
271 [
272 ("meta", &self.meta),
273 ("tags", &self.tags),
274 ("quote", &self.quote),
275 ("tests", &self.tests),
276 ("data_tests", &self.data_tests),
277 ("constraints", &self.constraints),
278 ("config", &self.config),
279 ("docs", &self.docs),
280 ("granularity", &self.granularity),
281 ]
282 .into_iter()
283 .filter_map(|(k, v)| v.is_some().then_some(k))
284 .collect()
285 }
286}