Skip to content

(GH-538) Set URI and docs keywords for DscRepoSchema types - #1699

Draft
Mikey Lombardi (He/Him) (michaeltlombardi) wants to merge 5 commits into
PowerShell:mainfrom
michaeltlombardi:gh-538/main/set-ids
Draft

(GH-538) Set URI and docs keywords for DscRepoSchema types#1699
Mikey Lombardi (He/Him) (michaeltlombardi) wants to merge 5 commits into
PowerShell:mainfrom
michaeltlombardi:gh-538/main/set-ids

Conversation

@michaeltlombardi

Copy link
Copy Markdown
Collaborator

PR Summary

This change:

  1. Defines new extension methods for operating on schemars::Schema instances:

    • [get|set]_title - Retrieve and override the title keyword as a string slice.
    • [get|set]_description - Retrieve and override the description keyword as a string slice.
    • set_markdown_description - Override the markdownDescription keyword as a string slice.
    • [get|set]_meta_schema - Retrieve and override the $schema keyword as a string slice.
    • get_meta_schema_as_url - Retrieve the $schema keyword as a Url.
    • has_meta_schema_keyword - Indicate whether schema defines the $schema keyword.
  2. Defines new transformer functions for the DscRepoSchema trait:

    • transform_export_schema_uris - Insert the $id and $schema keywords with the default_export_* function outputs.
    • transform_schema_docs - Insert the title, description, and markdownDescription keywords if they have defined localization strings.
    • transform_schema_docs_strict - Insert the title, description, and markdownDescription keywords if they have defined localization strings. If any translation strings are missing, panic.
  3. Updates the type definitions in dsc-lib for every type that derives or implements DscRepoSchema to ensure that the $id and $schema keywords are always populated and the docs keywords are defined if the translation strings are provided. Where the type was already using translated docs this change uses the strict transform to catch regressions in translation string definitions.

PR Context

Prior to this change the generated schemas were not consistently defining the $id and $schema keywords, which we need to properly populate for every schema that we publish in its own file. Additionally, the documentation keywords were manually inserted for every schema (that has translated docs already defined).

Effectively, before this PR, every struct needed a definition like the following when deriving JsonSchema and DscRepoSchema:

#[derive(Debug, Clone, JsonSchema, DscRepoSchema)]
#[dsc_repo_schema(base_name = "struct", folder_path = "example")]
#[schemars(
    title = schema_i18n!("title"),
    description = schema_i18n("description"),
    extend(
        "$schema" = ExampleStruct::default_export_meta_schema_uri(),
        "$id"     = ExampleStruct::default_export_schema_id_uri(),
        "markdownDescription" = schema_i18n!("markdownDescription"),
    )
)]
pub struct ExampleStruct {
    // Elided for brevity
}

With these changes, the definition now looks like:

#[derive(Debug, Clone, JsonSchema, DscRepoSchema)]
#[dsc_repo_schema(base_name = "struct", folder_path = "example")]
#[schemars(
    transform = ExampleStruct::transform_export_schema_uris,
    transform = ExampleStruct::transform_schema_docs,
)]
pub struct ExampleStruct {
  // Elided for brevity
}

This corrects various problems in the schema generation and export pipeline, which relies on the $id keyword to correctly manage bundled schema resources, and ensures that we can update the docs keywords for types without needing to modify the type definition directly.

Prior to this change, retrtieving the `title` and `description`
keywords from a schema required using the `get_keyword_as_str`
extension method. Setting `title`, `description`, and
`markdownDescription` required using the `insert` method on
the `Schema` and passing a `serde_json::Value`.

This change improves the ergonomics by defining the following
extension methods:

- `get_title` - retrieve the `title` keyword as a string
- `set_title` - override the `title` keyword, returning the
  previous value if it was defined.
- `get_description` - retrieve the `description` keyword
  as a string
- `set_description` - override the `description` keyword,
  returning the previous value if it was defined.
- `set_markdown_description` - override the `markdownDescription`
  keyword, returning the previous value if it was defined.
Prior to this change, working with the `$schema` field for a
schema required using the `get_keyword_as_str` method and
parsing into a `Url` or calling the `insert` method with a
`serde_json::Value`.

This change adds the following extension methods:

- `get_meta_schema` - Retrieve the `$schema` keyword as a
  string slice if defined.
- `get_meta_schema_as_url` - Retrieve the `$schema` keyword
  as a `Url` if defined and valid.
- `has_meta_schema_keyword` - Indicates if the schema defines
  the `$schema` keyword.
- `set_meta_schema` - Overrides the `$schema` keyword and
  returns the previous value if it was already defined.
Prior to this change, defining the `$schema`, `$id`, `title,
`description`, and `markdownDescription` keywords to the
JSON Schema for a `DscRepoSchema` type required the following
type definition pattern:

```rust
#[derive(Debug, Clone, JsonSchema, DscRepoSchema)]
#[dsc_repo_schema(base_name = "struct", folder_path = "example")]
#[schemars(
    title = schema_i18n!("title"),
    description = schema_i18n("description"),
    extend(
        "$schema" = ExampleStruct::default_export_meta_schema_uri(),
        "$id"     = ExampleStruct::default_export_schema_id_uri(),
        "markdownDescription" = schema_i18n!("markdownDescription"),
    )
)]
pub struct ExampleStruct {
    // Elided for brevity
}
```

With this change, you can insert the `$id` and `$schema` keywords with
the `transform_export_schema_uris` transform method and the localized
docs keywords with either the `transform_schema_docs` or
`transform_schema_docs_strict` methods.

```rust
#[derive(Debug, Clone, JsonSchema, DscRepoSchema)]
#[dsc_repo_schema(base_name = "struct", folder_path = "example")]
#[schemars(
    transform = ExampleStruct::transform_export_schema_uris,
    transform = ExampleStruct::transform_schema_docs,
)]
pub struct ExampleStruct {
  // Elided for brevity
}
```

This change adds the following transform methods to the `DscRepoSchema`
trait with default implementations for each transformer:

- `transform_export_schema_uris` - Insert the default export URIs for
  the `$schema` and `$id` keywords.
- `transform_schema_docs` - Insert the `title`, `description`, and
  `markdownDescription` keywords with localized text. If the translation
  is missing, silently skip overriding that keyword.
- `transform_schema_docs_strict` - As above, but collect missing
  translations and panic to indicate that the schema is missing docs.
Prior to this change, the schemas for `DscRepoSchema` types were
inconsistent about:

- Defining `$schema` and `$id` - some types deriving `JsonSchema`
  or implementing it manually supplied those keywords, most didn't.
  Some used `default_schema_id_uri` or `default_export_schema_id_uri`.
- Defining the documentation keywords. Most types didn't set them
  at all.

This change ensures every `DscRepoSchema` either defines the keywords
directly (for types manually implementing `JsonSchema`) or uses the
newly available `transform_*` associated trait functions (for types
that derive `JsonSchema`).

Most types _don't_ have localized documentation yet, so this PR
uses the non-strict transform. Eventually we should always use
the strict transforms and panic on missing documentation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant