Skip to content

Commit 73f84e6

Browse files
committed
refactor: Centralize doc comment handling
1 parent 99c1cdd commit 73f84e6

File tree

3 files changed

+50
-69
lines changed

3 files changed

+50
-69
lines changed

crates/stackable-versioned-macros/src/codegen/common/mod.rs

+46-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::collections::BTreeMap;
22

33
use k8s_version::Version;
4-
use proc_macro2::Span;
5-
use quote::format_ident;
4+
use proc_macro2::{Span, TokenStream};
5+
use quote::{format_ident, quote, ToTokens};
66
use syn::Ident;
77

88
use crate::{
@@ -34,24 +34,7 @@ pub(crate) struct ContainerVersion {
3434
pub(crate) ident: Ident,
3535

3636
/// Store additional doc-comment lines for this version.
37-
pub(crate) version_specific_docs: Vec<String>,
38-
}
39-
40-
/// Converts lines of doc-comments into a trimmed list.
41-
fn process_docs(input: &Option<String>) -> Vec<String> {
42-
if let Some(input) = input {
43-
input
44-
// Trim the leading and trailing whitespace, deleting suprefluous
45-
// empty lines.
46-
.trim()
47-
.lines()
48-
// Trim the leading and trailing whitespace on each line that can be
49-
// introduced when the developer indents multi-line comments.
50-
.map(|line| line.trim().to_owned())
51-
.collect()
52-
} else {
53-
Vec::new()
54-
}
37+
pub(crate) docs: Docs,
5538
}
5639

5740
impl From<&ContainerAttributes> for Vec<ContainerVersion> {
@@ -63,13 +46,55 @@ impl From<&ContainerAttributes> for Vec<ContainerVersion> {
6346
skip_from: v.skip.as_ref().map_or(false, |s| s.from.is_present()),
6447
ident: Ident::new(&v.name.to_string(), Span::call_site()),
6548
deprecated: v.deprecated.is_present(),
49+
docs: v.doc.clone().into(),
6650
inner: v.name,
67-
version_specific_docs: process_docs(&v.doc),
6851
})
6952
.collect()
7053
}
7154
}
7255

56+
#[derive(Clone, Debug)]
57+
pub(crate) struct Docs(Vec<String>);
58+
59+
impl From<Option<String>> for Docs {
60+
fn from(doc: Option<String>) -> Self {
61+
let lines = if let Some(doc) = doc {
62+
doc
63+
// Trim the leading and trailing whitespace, deleting
64+
// superfluous empty lines.
65+
.trim()
66+
.lines()
67+
// Trim the leading and trailing whitespace on each line that
68+
// can be introduced when the developer indents multi-line
69+
// comments.
70+
.map(|line| line.trim().into())
71+
.collect()
72+
} else {
73+
Vec::new()
74+
};
75+
76+
Self(lines)
77+
}
78+
}
79+
80+
impl ToTokens for Docs {
81+
fn to_tokens(&self, tokens: &mut TokenStream) {
82+
for (index, line) in self.0.iter().enumerate() {
83+
if index == 0 {
84+
// Prepend an empty line to clearly separate the version/action
85+
// specific docs.
86+
tokens.extend(quote! {
87+
#[doc = ""]
88+
})
89+
}
90+
91+
tokens.extend(quote! {
92+
#[doc = #line]
93+
})
94+
}
95+
}
96+
}
97+
7398
/// Removes the deprecated prefix from a field ident.
7499
///
75100
/// See [`DEPRECATED_FIELD_PREFIX`].

crates/stackable-versioned-macros/src/codegen/venum/mod.rs

+2-24
Original file line numberDiff line numberDiff line change
@@ -106,25 +106,23 @@ impl VersionedEnum {
106106
// enable the attribute macro to be applied to a module which
107107
// generates versioned versions of all contained containers.
108108

109+
let version_specific_docs = &version.docs;
109110
let version_ident = &version.ident;
110111

111112
let deprecated_note = format!("Version {version} is deprecated", version = version_ident);
112113
let deprecated_attr = version
113114
.deprecated
114115
.then_some(quote! {#[deprecated = #deprecated_note]});
115116

116-
// Generate doc comments for the container (enum)
117-
let version_specific_docs = self.generate_enum_docs(version);
118-
119117
// Generate tokens for the module and the contained enum
120118
token_stream.extend(quote! {
121119
#[automatically_derived]
122120
#deprecated_attr
123121
#visibility mod #version_ident {
124122
use super::*;
125123

126-
#version_specific_docs
127124
#(#original_attributes)*
125+
#version_specific_docs
128126
pub enum #enum_name {
129127
#variants
130128
}
@@ -139,26 +137,6 @@ impl VersionedEnum {
139137
token_stream
140138
}
141139

142-
/// Generates version specific doc comments for the enum.
143-
fn generate_enum_docs(&self, version: &ContainerVersion) -> TokenStream {
144-
let mut tokens = TokenStream::new();
145-
146-
for (i, doc) in version.version_specific_docs.iter().enumerate() {
147-
if i == 0 {
148-
// Prepend an empty line to clearly separate the version
149-
// specific docs.
150-
tokens.extend(quote! {
151-
#[doc = ""]
152-
})
153-
}
154-
tokens.extend(quote! {
155-
#[doc = #doc]
156-
})
157-
}
158-
159-
tokens
160-
}
161-
162140
fn generate_enum_variants(&self, version: &ContainerVersion) -> TokenStream {
163141
let mut token_stream = TokenStream::new();
164142

crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs

+2-24
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,14 @@ impl VersionedStruct {
126126
// enable the attribute macro to be applied to a module which
127127
// generates versioned versions of all contained containers.
128128

129+
let version_specific_docs = &version.docs;
129130
let version_ident = &version.ident;
130131

131132
let deprecated_note = format!("Version {version} is deprecated", version = version_ident);
132133
let deprecated_attr = version
133134
.deprecated
134135
.then_some(quote! {#[deprecated = #deprecated_note]});
135136

136-
// Generate doc comments for the container (struct)
137-
let version_specific_docs = self.generate_struct_docs(version);
138-
139137
// Generate K8s specific code
140138
let kubernetes_cr_derive = self.generate_kubernetes_cr_derive(version);
141139

@@ -146,8 +144,8 @@ impl VersionedStruct {
146144
#visibility mod #version_ident {
147145
use super::*;
148146

149-
#version_specific_docs
150147
#(#original_attributes)*
148+
#version_specific_docs
151149
#kubernetes_cr_derive
152150
pub struct #struct_name {
153151
#fields
@@ -163,26 +161,6 @@ impl VersionedStruct {
163161
token_stream
164162
}
165163

166-
/// Generates version specific doc comments for the struct.
167-
fn generate_struct_docs(&self, version: &ContainerVersion) -> TokenStream {
168-
let mut tokens = TokenStream::new();
169-
170-
for (i, doc) in version.version_specific_docs.iter().enumerate() {
171-
if i == 0 {
172-
// Prepend an empty line to clearly separate the version
173-
// specific docs.
174-
tokens.extend(quote! {
175-
#[doc = ""]
176-
})
177-
}
178-
tokens.extend(quote! {
179-
#[doc = #doc]
180-
})
181-
}
182-
183-
tokens
184-
}
185-
186164
/// Generates struct fields following the `name: type` format which includes
187165
/// a trailing comma.
188166
fn generate_struct_fields(&self, version: &ContainerVersion) -> TokenStream {

0 commit comments

Comments
 (0)