Skip to content

Commit 136c9f8

Browse files
(GH-538) Use derive macro for DscRepoSchema trait
Prior to this change, the resource manifest, extension manifest, and configuration document structs in `dsc-lib` manually implemented the `DscRepoSchema` trait. This change uses the new macro to derive the trait on those types and other types in the library that currently map to schema files. This change also makes an effort to correctly annotate types that aren't covered by the separate schemas, but as not all types map to a schema file, these changes don't fully cover all types that derive the `JsonSchema` trait. This change prepares the library for further canonicalization steps to steer the generated schemas towards the definitions in the canonical schemas.
1 parent 042cf56 commit 136c9f8

File tree

11 files changed

+160
-138
lines changed

11 files changed

+160
-138
lines changed

lib/dsc-lib/src/configure/config_doc.rs

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,41 @@
33

44
use chrono::{DateTime, Local};
55
use rust_i18n::t;
6-
use schemars::{JsonSchema, json_schema};
6+
use schemars::JsonSchema;
77
use serde::{Deserialize, Deserializer, Serialize};
88
use serde_json::{Map, Value};
99
use std::{collections::HashMap, fmt::Display};
1010

1111
use crate::schemas::{
12-
dsc_repo::{DscRepoSchema, UnrecognizedSchemaUri},
12+
dsc_repo::DscRepoSchema,
1313
transforms::{idiomaticize_externally_tagged_enum, idiomaticize_string_enum}
1414
};
1515

16-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
16+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
1717
#[serde(rename_all = "camelCase")]
1818
#[schemars(transform = idiomaticize_string_enum)]
19+
#[dsc_repo_schema(base_name = "securityContext", folder_path = "metadata/Microsoft.DSC")]
1920
pub enum SecurityContextKind {
2021
Current,
2122
Elevated,
2223
Restricted,
2324
}
2425

25-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
26+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
2627
#[serde(rename_all = "camelCase")]
2728
#[schemars(transform = idiomaticize_string_enum)]
29+
#[dsc_repo_schema(base_name = "operation", folder_path = "metadata/Microsoft.DSC")]
2830
pub enum Operation {
2931
Get,
3032
Set,
3133
Test,
3234
Export,
3335
}
3436

35-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
37+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
3638
#[serde(rename_all = "camelCase")]
3739
#[schemars(transform = idiomaticize_string_enum)]
40+
#[dsc_repo_schema(base_name = "executionType", folder_path = "metadata/Microsoft.DSC")]
3841
pub enum ExecutionKind {
3942
Actual,
4043
WhatIf,
@@ -47,9 +50,10 @@ pub struct Process {
4750
pub id: u32,
4851
}
4952

50-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
53+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
5154
#[serde(rename_all = "camelCase")]
5255
#[schemars(transform = idiomaticize_externally_tagged_enum)]
56+
#[dsc_repo_schema(base_name = "restartRequired", folder_path = "metadata/Microsoft.DSC")]
5357
pub enum RestartRequired {
5458
System(String),
5559
Service(String),
@@ -104,33 +108,38 @@ impl MicrosoftDscMetadata {
104108
}
105109
}
106110

107-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
111+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
112+
#[dsc_repo_schema(base_name = "document.metadata", folder_path = "config")]
108113
pub struct Metadata {
109114
#[serde(rename = "Microsoft.DSC", skip_serializing_if = "Option::is_none")]
110115
pub microsoft: Option<MicrosoftDscMetadata>,
111116
#[serde(flatten)]
112117
pub other: Map<String, Value>,
113118
}
114119

115-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
120+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
121+
#[dsc_repo_schema(base_name = "document.function", folder_path = "config")]
116122
pub struct UserFunction {
117123
pub namespace: String,
118124
pub members: HashMap<String, UserFunctionDefinition>,
119125
}
120126

121-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
127+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
128+
#[dsc_repo_schema(base_name = "definition", folder_path = "definitions/functions/user")]
122129
pub struct UserFunctionDefinition {
123130
pub parameters: Option<Vec<UserFunctionParameter>>,
124131
pub output: UserFunctionOutput,
125132
}
126133

127-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
134+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
135+
#[dsc_repo_schema(base_name = "parameter", folder_path = "definitions/functions/user")]
128136
pub struct UserFunctionParameter {
129137
pub name: String,
130138
pub r#type: DataType,
131139
}
132140

133-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
141+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
142+
#[dsc_repo_schema(base_name = "output", folder_path = "definitions/functions/user")]
134143
pub struct UserFunctionOutput {
135144
pub r#type: DataType,
136145
pub value: String,
@@ -143,17 +152,28 @@ pub enum ValueOrCopy {
143152
Copy(Copy),
144153
}
145154

146-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
155+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
147156
#[serde(deny_unknown_fields)]
157+
#[dsc_repo_schema(base_name = "document.output", folder_path = "config")]
148158
pub struct Output {
149159
pub condition: Option<String>,
150160
pub r#type: DataType,
151161
#[serde(flatten)]
152162
pub value_or_copy: ValueOrCopy,
153163
}
154164

155-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
165+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
156166
#[serde(deny_unknown_fields)]
167+
#[dsc_repo_schema(
168+
base_name = "document",
169+
folder_path = "config",
170+
should_bundle = true,
171+
schema_field(
172+
name = schema,
173+
title = t!("configure.config_doc.configurationDocumentSchemaTitle"),
174+
description = t!("configure.config_doc.configurationDocumentSchemaDescription"),
175+
)
176+
)]
157177
pub struct Configuration {
158178
#[serde(rename = "$schema")]
159179
#[schemars(schema_with = "Configuration::recognized_schema_uris_subschema")]
@@ -222,8 +242,9 @@ where
222242
}
223243
}
224244

225-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
245+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
226246
#[serde(deny_unknown_fields)]
247+
#[dsc_repo_schema(base_name = "document.parameter", folder_path = "config")]
227248
pub struct Parameter {
228249
#[serde(rename = "type")]
229250
pub parameter_type: DataType,
@@ -245,8 +266,9 @@ pub struct Parameter {
245266
pub metadata: Option<Map<String, Value>>,
246267
}
247268

248-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
269+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
249270
#[schemars(transform = idiomaticize_string_enum)]
271+
#[dsc_repo_schema(base_name = "dataTypes", folder_path = "definitions/parameters")]
250272
pub enum DataType {
251273
#[serde(rename = "string")]
252274
String,
@@ -353,8 +375,9 @@ pub struct Sku {
353375
pub capacity: Option<i32>,
354376
}
355377

356-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
378+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
357379
#[serde(deny_unknown_fields)]
380+
#[dsc_repo_schema(base_name = "document.resource", folder_path = "config")]
358381
pub struct Resource {
359382
#[serde(skip_serializing_if = "Option::is_none")]
360383
pub condition: Option<String>,
@@ -406,30 +429,6 @@ impl Default for Configuration {
406429
}
407430
}
408431

409-
impl DscRepoSchema for Configuration {
410-
const SCHEMA_FILE_BASE_NAME: &'static str = "document";
411-
const SCHEMA_FOLDER_PATH: &'static str = "config";
412-
const SCHEMA_SHOULD_BUNDLE: bool = true;
413-
414-
fn schema_property_metadata() -> schemars::Schema {
415-
json_schema!({
416-
"title": t!("configure.config_doc.configurationDocumentSchemaTitle").to_string(),
417-
"description": t!("configure.config_doc.configurationDocumentSchemaDescription").to_string(),
418-
})
419-
}
420-
421-
fn validate_schema_uri(&self) -> Result<(), UnrecognizedSchemaUri> {
422-
if Self::is_recognized_schema_uri(&self.schema) {
423-
Ok(())
424-
} else {
425-
Err(UnrecognizedSchemaUri(
426-
self.schema.clone(),
427-
Self::recognized_schema_uris(),
428-
))
429-
}
430-
}
431-
}
432-
433432
impl Configuration {
434433
#[must_use]
435434
pub fn new() -> Self {

lib/dsc-lib/src/configure/config_result.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde_json::{Map, Value};
77

88
use crate::dscresources::invoke_result::{GetResult, SetResult, TestResult};
99
use crate::configure::config_doc::{Configuration, Metadata};
10-
use crate::schemas::transforms::idiomaticize_string_enum;
10+
use crate::schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum};
1111

1212
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
1313
#[serde(rename_all = "camelCase")]
@@ -18,8 +18,9 @@ pub enum MessageLevel {
1818
Information,
1919
}
2020

21-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
21+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
2222
#[serde(deny_unknown_fields)]
23+
#[dsc_repo_schema(base_name = "message", folder_path = "definitions")]
2324
pub struct ResourceMessage {
2425
pub name: String,
2526
#[serde(rename="type")]
@@ -28,8 +29,9 @@ pub struct ResourceMessage {
2829
pub level: MessageLevel,
2930
}
3031

31-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
32+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
3233
#[serde(deny_unknown_fields)]
34+
#[dsc_repo_schema(base_name = "get.full", folder_path = "outputs/resource")]
3335
pub struct ResourceGetResult {
3436
#[serde(skip_serializing_if = "Option::is_none")]
3537
pub metadata: Option<Metadata>,
@@ -50,8 +52,9 @@ impl From<ResourceTestResult> for ResourceGetResult {
5052
}
5153
}
5254

53-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
55+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
5456
#[serde(deny_unknown_fields)]
57+
#[dsc_repo_schema(base_name = "get", folder_path = "outputs/config")]
5558
pub struct ConfigurationGetResult {
5659
pub metadata: Option<Metadata>,
5760
pub results: Vec<ResourceGetResult>,
@@ -97,8 +100,9 @@ impl From<ConfigurationTestResult> for ConfigurationGetResult {
97100
}
98101
}
99102

100-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
103+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
101104
#[serde(deny_unknown_fields)]
105+
#[dsc_repo_schema(base_name = "set.full", folder_path = "outputs/resource")]
102106
pub struct ResourceSetResult {
103107
#[serde(skip_serializing_if = "Option::is_none")]
104108
pub metadata: Option<Metadata>,
@@ -140,8 +144,9 @@ impl Default for GroupResourceSetResult {
140144
}
141145
}
142146

143-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
147+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
144148
#[serde(deny_unknown_fields)]
149+
#[dsc_repo_schema(base_name = "set", folder_path = "outputs/config")]
145150
pub struct ConfigurationSetResult {
146151
pub metadata: Option<Metadata>,
147152
pub results: Vec<ResourceSetResult>,
@@ -171,8 +176,9 @@ impl Default for ConfigurationSetResult {
171176
}
172177
}
173178

174-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
179+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
175180
#[serde(deny_unknown_fields)]
181+
#[dsc_repo_schema(base_name = "test.full", folder_path = "outputs/resource")]
176182
pub struct ResourceTestResult {
177183
#[serde(skip_serializing_if = "Option::is_none")]
178184
pub metadata: Option<Metadata>,
@@ -203,8 +209,9 @@ impl Default for GroupResourceTestResult {
203209
}
204210
}
205211

206-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
212+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
207213
#[serde(deny_unknown_fields)]
214+
#[dsc_repo_schema(base_name = "test", folder_path = "outputs/config")]
208215
pub struct ConfigurationTestResult {
209216
pub metadata: Option<Metadata>,
210217
pub results: Vec<ResourceTestResult>,
@@ -234,8 +241,9 @@ impl Default for ConfigurationTestResult {
234241
}
235242
}
236243

237-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
244+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
238245
#[serde(deny_unknown_fields)]
246+
#[dsc_repo_schema(base_name = "export", folder_path = "outputs/config")]
239247
pub struct ConfigurationExportResult {
240248
pub metadata: Option<Metadata>,
241249
pub result: Option<Configuration>,

lib/dsc-lib/src/dscresources/dscresource.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use std::collections::HashMap;
1414
use std::path::PathBuf;
1515
use tracing::{debug, info, trace};
1616

17+
use crate::schemas::dsc_repo::DscRepoSchema;
18+
1719
use super::{
1820
command_resource,
1921
dscerror,
@@ -25,8 +27,9 @@ use super::{
2527
}
2628
};
2729

28-
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
30+
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
2931
#[serde(deny_unknown_fields)]
32+
#[dsc_repo_schema(base_name = "list", folder_path = "outputs/resource")]
3033
pub struct DscResource {
3134
/// The namespaced name of the resource.
3235
#[serde(rename="type")]
@@ -59,9 +62,10 @@ pub struct DscResource {
5962
pub manifest: Option<Value>,
6063
}
6164

62-
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
65+
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)]
6366
#[serde(rename_all = "camelCase")]
6467
#[schemars(transform = idiomaticize_string_enum)]
68+
#[dsc_repo_schema(base_name = "resourceCapabilities", folder_path = "definitions")]
6569
pub enum Capability {
6670
/// The resource supports retrieving configuration.
6771
Get,

0 commit comments

Comments
 (0)