Skip to content

Commit

Permalink
new: Docblocks polish. (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj committed Jul 22, 2024
1 parent 66732aa commit 7ee2d8e
Show file tree
Hide file tree
Showing 27 changed files with 191 additions and 59 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## Unreleased

#### 🚀 Updates

- We now track `#[deprecated]` on containers.
- TypeScript
- When rendering a struct field that has an enum type, we'll include a `@type` doc tag for all
variants.
- Deprecated structs (interfaces) and enums will now contain `@deprecated` on the container.

#### ⚙️ Internal

- Updated `garde` (validation) to v0.20.
Expand Down
23 changes: 16 additions & 7 deletions crates/macros/src/common/container.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::common::{Field, Variant};
use crate::utils::map_option_argument_quote;
use crate::utils::{extract_comment, extract_deprecated, map_option_argument_quote};
use proc_macro2::TokenStream;
use quote::quote;
use syn::Fields;
use syn::{Attribute, Fields};

pub enum Container<'l> {
NamedStruct { fields: Vec<Field<'l>> },
Expand All @@ -19,11 +19,14 @@ impl<'l> Container<'l> {
}
}

pub fn generate_schema(&self, description: Option<String>) -> TokenStream {
let description = if let Some(comment) = description {
quote! {
schema.set_description(#comment);
}
pub fn generate_schema(&self, attrs: &[&Attribute]) -> TokenStream {
let deprecated = if let Some(comment) = extract_deprecated(attrs) {
quote! { schema.set_deprecated(#comment); }
} else {
quote! {}
};
let description = if let Some(comment) = extract_comment(attrs) {
quote! { schema.set_description(#comment); }
} else {
quote! {}
};
Expand All @@ -43,11 +46,13 @@ impl<'l> Container<'l> {

if fields.is_empty() {
quote! {
#deprecated
#description
schema.structure(StructType::default())
}
} else {
quote! {
#deprecated
#description
schema.structure(StructType::new([
#(#schema_types),*
Expand All @@ -72,11 +77,13 @@ impl<'l> Container<'l> {

quote! {
let mut schema = #single_type;
#deprecated
#description
schema
}
} else {
quote! {
#deprecated
#description
schema.tuple(TupleType::new([
#(#schema_types),*
Expand Down Expand Up @@ -110,6 +117,7 @@ impl<'l> Container<'l> {

if is_all_unit_enum {
quote! {
#deprecated
#description
schema.enumerable(EnumType::from_schemas(
[
Expand All @@ -120,6 +128,7 @@ impl<'l> Container<'l> {
}
} else {
quote! {
#deprecated
#description
schema.union(UnionType::from_schemas(
[
Expand Down
4 changes: 1 addition & 3 deletions crates/macros/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,8 @@ impl<'l> ToTokens for ConfigMacro<'l> {

#[cfg(feature = "schema")]
{
use crate::utils::extract_comment;

let schema_name = cfg.get_name();
let schema_impl = cfg.type_of.generate_schema(extract_comment(&cfg.attrs));
let schema_impl = cfg.type_of.generate_schema(&cfg.attrs);

let partial_schema_name = partial_name.to_string();
let partial_schema_impl = cfg.type_of.generate_partial_schema(name, &partial_name);
Expand Down
9 changes: 7 additions & 2 deletions crates/macros/src/config_enum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod variant;

use crate::common::ContainerSerdeArgs;
use crate::config_enum::variant::Variant;
use crate::utils::{extract_comment, extract_common_attrs, instrument_quote};
use crate::utils::{extract_comment, extract_common_attrs, extract_deprecated, instrument_quote};
use darling::FromDeriveInput;
use proc_macro::TokenStream;
use quote::quote;
Expand Down Expand Up @@ -178,6 +178,11 @@ pub fn macro_impl(item: TokenStream) -> TokenStream {
let default_index = map_option_argument_quote(default_index);
let instrument = instrument_quote();

let deprecated = if let Some(comment) = extract_deprecated(&attrs) {
quote! { schema.set_deprecated(#comment); }
} else {
quote! {}
};
let description = if let Some(comment) = extract_comment(&attrs) {
quote! { schema.set_description(#comment); }
} else {
Expand All @@ -194,7 +199,7 @@ pub fn macro_impl(item: TokenStream) -> TokenStream {
#instrument
fn build_schema(mut schema: schematic::SchemaBuilder) -> schematic::Schema {
use schematic::schema::*;

#deprecated
#description
schema.enumerable(EnumType::from_fields(
[
Expand Down
4 changes: 2 additions & 2 deletions crates/macros/src/schematic/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::common::Macro;
use crate::utils::{extract_comment, instrument_quote};
use crate::utils::instrument_quote;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};

Expand All @@ -11,7 +11,7 @@ impl<'l> ToTokens for SchematicMacro<'l> {
let name = cfg.name;

let schema_name = cfg.get_name();
let schema_impl = cfg.type_of.generate_schema(extract_comment(&cfg.attrs));
let schema_impl = cfg.type_of.generate_schema(&cfg.attrs);
let instrument = instrument_quote();

tokens.extend(quote! {
Expand Down
1 change: 1 addition & 0 deletions crates/schematic/src/schema/renderers/json_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ impl<'gen> JsonSchemaRenderer<'gen> {
} else {
schema.name.clone()
},
deprecated: schema.deprecated.is_some(),
description: schema
.description
.clone()
Expand Down
87 changes: 58 additions & 29 deletions crates/schematic/src/schema/renderers/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl<'gen> TypeScriptRenderer<'gen> {

fn export_enum_type(&mut self, name: &str, enu: &EnumType, schema: &Schema) -> RenderResult {
let value = self.render_enum(enu, schema)?;
let mut tags = vec![];

let output = if self.is_string_union_enum(enu) {
self.export_type_alias(name, value)?
Expand All @@ -139,7 +140,15 @@ impl<'gen> TypeScriptRenderer<'gen> {
}
};

Ok(self.wrap_in_comment(schema.description.as_ref(), vec![], output))
if let Some(deprecated) = &schema.deprecated {
tags.push(if deprecated.is_empty() {
"@deprecated".to_owned()
} else {
format!("@deprecated {deprecated}")
});
}

Ok(self.wrap_in_comment(schema.description.as_ref(), tags, output))
}

fn export_object_type(
Expand All @@ -149,45 +158,58 @@ impl<'gen> TypeScriptRenderer<'gen> {
schema: &Schema,
) -> RenderResult {
let value = self.render_struct(structure, schema)?;
let mut tags = vec![];

let output = if matches!(self.options.object_format, ObjectFormat::Interface) {
format!("export interface {name} {value}")
} else {
self.export_type_alias(name, value)?
};

Ok(self.wrap_in_comment(schema.description.as_ref(), vec![], output))
if let Some(deprecated) = &schema.deprecated {
tags.push(if deprecated.is_empty() {
"@deprecated".to_owned()
} else {
format!("@deprecated {deprecated}")
});
}

Ok(self.wrap_in_comment(schema.description.as_ref(), tags, output))
}

fn render_enum_as_string_union(&mut self, enu: &EnumType, schema: &Schema) -> RenderResult {
// Map using variants instead of values (when available),
// so that the fallback variant is included
let variants_types = if let Some(variants) = &enu.variants {
variants
.iter()
.filter_map(|(_, variant)| {
if variant.hidden {
None
} else {
Some(Box::new(variant.schema.clone()))
}
})
.collect::<Vec<_>>()
} else {
enu.values
.iter()
.map(|v| Box::new(Schema::literal_value(v.clone())))
.collect::<Vec<_>>()
};

self.render_union(
&UnionType {
variants_types,
..Default::default()
},
schema,
)
}

fn render_enum_or_union(&mut self, enu: &EnumType, schema: &Schema) -> RenderResult {
if self.is_string_union_enum(enu) {
// Map using variants instead of values (when available),
// so that the fallback variant is included
let variants_types = if let Some(variants) = &enu.variants {
variants
.iter()
.filter_map(|(_, variant)| {
if variant.hidden {
None
} else {
Some(Box::new(variant.schema.clone()))
}
})
.collect::<Vec<_>>()
} else {
enu.values
.iter()
.map(|v| Box::new(Schema::literal_value(v.clone())))
.collect::<Vec<_>>()
};

return self.render_union(
&UnionType {
variants_types,
..Default::default()
},
schema,
);
return self.render_enum_as_string_union(enu, schema);
}

self.depth += 1;
Expand Down Expand Up @@ -431,6 +453,13 @@ impl<'gen> SchemaRenderer<'gen, String> for TypeScriptRenderer<'gen> {
tags.push(format!("@envvar {env_var}"));
}

if let SchemaType::Enum(inner) = &field.schema.ty {
tags.push(format!(
"@type {{{}}}",
self.render_enum_as_string_union(inner, &field.schema)?
));
}

out.push(self.wrap_in_comment(field.comment.as_ref(), tags, row));
}

Expand Down
1 change: 1 addition & 0 deletions crates/schematic/tests/generator_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub struct AnotherConfig {
}

#[derive(Clone, Config)]
#[deprecated]
struct GenConfig {
boolean: bool,
string: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: "fs::read_to_string(file).unwrap()"
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "GenConfig",
"deprecated": true,
"type": "object",
"required": [
"boolean",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: "fs::read_to_string(file).unwrap()"
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "GenConfig",
"deprecated": true,
"type": "object",
"properties": {
"boolean": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: "fs::read_to_string(file).unwrap()"
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PartialGenConfig",
"deprecated": true,
"type": "object",
"properties": {
"boolean": {
Expand Down Expand Up @@ -365,6 +366,7 @@ expression: "fs::read_to_string(file).unwrap()"
},
"GenConfig": {
"title": "GenConfig",
"deprecated": true,
"type": "object",
"required": [
"boolean",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: "fs::read_to_string(file).unwrap()"
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "GenConfig",
"deprecated": true,
"type": "object",
"required": [
"boolean",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ expression: "fs::read_to_string(file).unwrap()"
---
{
"$schema": "http://json-schema.org/draft-07/schema#",
"deprecated": true,
"type": "object",
"required": [
"boolean",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface AnotherConfig {
opt: string | null;
}

/** @deprecated */
export interface GenConfig {
boolean: boolean;
date: string;
Expand All @@ -36,9 +37,13 @@ export interface GenConfig {
* This is a list of `enumerable` values.
*
* @default 'foo'
* @type {'foo' | 'bar' | 'baz'}
*/
enums: BasicEnum;
/** @default 'foo' */
/**
* @default 'foo'
* @type {'foo' | 'bar' | 'baz' | string}
*/
fallbackEnum: FallbackEnum;
float32: number;
float64: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface AnotherConfig {
opt: string | null;
}

/** @deprecated */
export interface GenConfig {
boolean: boolean;
date: string;
Expand All @@ -32,9 +33,13 @@ export interface GenConfig {
* This is a list of `enumerable` values.
*
* @default 'foo'
* @type {'foo' | 'bar' | 'baz'}
*/
enums: BasicEnum;
/** @default 'foo' */
/**
* @default 'foo'
* @type {'foo' | 'bar' | 'baz' | string}
*/
fallbackEnum: FallbackEnum;
float32: number;
float64: number;
Expand Down
Loading

0 comments on commit 7ee2d8e

Please sign in to comment.