Skip to content

Commit 6afcd0e

Browse files
committed
docs: Add doc and developer comments
1 parent 709e6f6 commit 6afcd0e

File tree

7 files changed

+95
-28
lines changed

7 files changed

+95
-28
lines changed

crates/stackable-versioned-macros/src/codegen/chain.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ impl<K, V> Neighbors<K, V> for BTreeMap<K, V>
1414
where
1515
K: Ord + Eq,
1616
{
17+
/// Returns the values of keys which are neighbors of `key`.
18+
///
19+
/// Imagine a map which contains the following keys: 1, 3, 5. Calling this
20+
/// function with these keys, results in the following return values:
21+
///
22+
/// - Key **0**: `(None, Some(1))`
23+
/// - Key **2**: `(Some(1), Some(3))`
24+
/// - Key **4**: `(Some(3), Some(5))`
25+
/// - Key **6**: `(Some(5), None)`
1726
fn get_neighbors(&self, key: &K) -> (Option<&V>, Option<&V>) {
1827
// NOTE (@Techassi): These functions might get added to the standard
1928
// library at some point. If that's the case, we can use the ones

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,22 @@ use syn::Ident;
55

66
use crate::{attrs::common::ContainerAttributes, codegen::common::ContainerVersion};
77

8+
/// This trait helps to unify versioned containers, like structs and enums.
9+
///
10+
/// This trait is implemented by wrapper structs, which wrap the generic
11+
/// [`VersionedContainer`] struct. The generic type parameter `D` describes the
12+
/// kind of data, like [`DataStruct`](syn::DataStruct) in case of a struct and
13+
/// [`DataEnum`](syn::DataEnum) in case of an enum.
14+
/// The type parameter `I` describes the type of the versioned items, like
15+
/// [`VersionedField`][1] and [`VersionedVariant`][2].
16+
///
17+
/// [1]: crate::codegen::vstruct::field::VersionedField
18+
/// [2]: crate::codegen::venum::variant::VersionedVariant
819
pub(crate) trait Container<D, I>
920
where
1021
Self: Sized + Deref<Target = VersionedContainer<I>>,
1122
{
23+
/// Creates a new versioned container.
1224
fn new(ident: Ident, data: D, attributes: ContainerAttributes) -> syn::Result<Self>;
1325

1426
/// This generates the complete code for a single versioned container.

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,40 @@ where
4343
fn get_ident(&self, version: &ContainerVersion) -> Option<&Ident>;
4444
}
4545

46+
/// This trait enables access to the ident of named items, like fields and
47+
/// variants.
48+
///
49+
/// It additionally provides a function to retrieve the cleaned ident, which
50+
/// removes the deprecation prefixes.
4651
pub(crate) trait Named {
4752
fn cleaned_ident(&self) -> Ident;
4853
fn ident(&self) -> &Ident;
4954
}
5055

56+
/// This trait enables access to the common attributes across field and variant
57+
/// attributes.
5158
pub(crate) trait Attributes {
5259
fn common_attrs_owned(self) -> ItemAttributes;
5360
fn common_attrs(&self) -> &ItemAttributes;
5461
}
5562

63+
/// This struct combines common common code for versioned fields and variants.
64+
///
65+
/// Most of the initial creation of a versioned field and variant are identical.
66+
/// Currently, the following steps are unified:
67+
///
68+
/// - Initial creation of the action chain based on item attributes.
69+
/// - Insertion of container versions into the chain.
70+
///
71+
/// The generic type parameter `I` describes the type of the versioned item,
72+
/// usually [`Field`](syn::Field) or [`Variant`](syn::Variant). The parameter
73+
/// `A` indicates the type of item attributes, usually [`FieldAttributes`][1] or
74+
/// [`VariantAttributes`][2] depending on the used item type. As this type is
75+
/// only needed during creation of [`Self`](VersionedItem), we must use a
76+
/// [`PhantomData`] marker.
77+
///
78+
/// [1]: crate::attrs::field::FieldAttributes
79+
/// [2]: crate::attrs::variant::VariantAttributes
5680
#[derive(Debug)]
5781
pub(crate) struct VersionedItem<I, A>
5882
where
@@ -71,6 +95,11 @@ where
7195
I: Named + Spanned,
7296
{
7397
fn new(item: I, container_attrs: &ContainerAttributes) -> syn::Result<Self> {
98+
// We use the TryFrom trait here, because the type parameter `A` can use
99+
// it as a trait bound. Internally this then calls either `from_field`
100+
// for field attributes or `from_variant` for variant attributes. Sadly
101+
// darling doesn't provide a "generic" trait which abstracts over the
102+
// different `from_` functions.
74103
let attrs = A::try_from(&item)?;
75104
attrs.validate_versions(container_attrs, &item)?;
76105

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod item;
1616
pub(crate) use container::*;
1717
pub(crate) use item::*;
1818

19+
/// Type alias to make the type of the version chain easier to handle.
1920
pub(crate) type VersionChain = BTreeMap<Version, ItemStatus>;
2021

2122
#[derive(Debug, Clone)]
@@ -53,15 +54,22 @@ pub(crate) fn format_container_from_ident(ident: &Ident) -> Ident {
5354
format_ident!("__sv_{ident}", ident = ident.to_string().to_lowercase())
5455
}
5556

56-
/// Removes the deprecated prefix from field ident.
57+
/// Removes the deprecated prefix from a field ident.
58+
///
59+
/// See [`DEPRECATED_FIELD_PREFIX`].
5760
pub(crate) fn remove_deprecated_field_prefix(ident: &Ident) -> Ident {
5861
remove_ident_prefix(ident, DEPRECATED_FIELD_PREFIX)
5962
}
6063

64+
/// Removes the deprecated prefix from a variant ident.
65+
///
66+
/// See [`DEPRECATED_VARIANT_PREFIX`].
6167
pub(crate) fn remove_deprecated_variant_prefix(ident: &Ident) -> Ident {
6268
remove_ident_prefix(ident, DEPRECATED_VARIANT_PREFIX)
6369
}
6470

71+
/// Removes the provided prefix from an ident and returns the newly created
72+
/// ident.
6573
pub(crate) fn remove_ident_prefix(ident: &Ident, prefix: &str) -> Ident {
6674
format_ident!("{}", ident.to_string().trim_start_matches(prefix))
6775
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub(crate) mod variant;
2020
/// Stores individual versions of a single enum. Each version tracks variant
2121
/// actions, which describe if the variant was added, renamed or deprecated in
2222
/// that version. Variants which are not versioned, are included in every
23-
/// version of the struct.
23+
/// version of the enum.
2424
#[derive(Debug)]
2525
pub(crate) struct VersionedEnum(VersionedContainer<VersionedVariant>);
2626

@@ -61,7 +61,7 @@ impl Container<DataEnum, VersionedVariant> for VersionedEnum {
6161
if !items.iter().map(|f| f.get_ident(version)).all_unique() {
6262
return Err(Error::new(
6363
ident.span(),
64-
format!("struct contains renamed fields which collide with other fields in version {version}", version = version.inner),
64+
format!("Enum contains renamed variants which collide with other variants in version {version}", version = version.inner),
6565
));
6666
}
6767
}
@@ -115,7 +115,7 @@ impl VersionedEnum {
115115
.deprecated
116116
.then_some(quote! {#[deprecated = #deprecated_note]});
117117

118-
// Generate tokens for the module and the contained struct
118+
// Generate tokens for the module and the contained enum
119119
token_stream.extend(quote! {
120120
#[automatically_derived]
121121
#deprecated_attr

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

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ use crate::{
1919
},
2020
};
2121

22+
/// A versioned variant, which contains contains common [`Variant`] data and a
23+
/// chain of actions.
24+
///
25+
/// The chain of action maps versions to an action and the appropriate variant
26+
/// name. Additionally, the [`Variant`] data can be used to forward attributes,
27+
/// generate documentation, etc.
2228
#[derive(Debug)]
2329
pub(crate) struct VersionedVariant(VersionedItem<Variant, VariantAttributes>);
2430

@@ -56,20 +62,19 @@ impl Attributes for VariantAttributes {
5662

5763
impl Named for Variant {
5864
fn cleaned_ident(&self) -> Ident {
59-
let ident = self.ident();
60-
remove_deprecated_variant_prefix(ident)
65+
remove_deprecated_variant_prefix(self.ident())
6166
}
6267

6368
fn ident(&self) -> &Ident {
6469
&self.ident
6570
}
6671
}
6772

68-
// TODO (@Techassi): Figure out a way to be able to only write the following code
69-
// once for both a versioned field and variant, because the are practically
70-
// identical.
71-
7273
impl VersionedVariant {
74+
/// Creates a new versioned variant.
75+
///
76+
/// Internally this calls [`VersionedItem::new`] to handle most of the
77+
/// common creation code.
7378
pub(crate) fn new(
7479
variant: Variant,
7580
container_attributes: &ContainerAttributes,
@@ -78,15 +83,19 @@ impl VersionedVariant {
7883
Ok(Self(item))
7984
}
8085

86+
/// Generates tokens to be used in a container definition.
8187
pub(crate) fn generate_for_container(
8288
&self,
8389
container_version: &ContainerVersion,
8490
) -> Option<TokenStream> {
8591
match &self.chain {
86-
Some(chain) => match chain
87-
.get(&container_version.inner)
88-
.expect("internal error: chain must contain container version")
89-
{
92+
// NOTE (@Techassi): https://rust-lang.github.io/rust-clippy/master/index.html#/expect_fun_call
93+
Some(chain) => match chain.get(&container_version.inner).unwrap_or_else(|| {
94+
panic!(
95+
"internal error: chain must contain container version {}",
96+
container_version.inner
97+
)
98+
}) {
9099
ItemStatus::Added { ident, .. } => Some(quote! {
91100
#ident,
92101
}),
@@ -115,6 +124,7 @@ impl VersionedVariant {
115124
}
116125
}
117126

127+
/// Generates tokens to be used in a [`From`] implementation.
118128
pub(crate) fn generate_for_from_impl(
119129
&self,
120130
module_name: &Ident,
@@ -151,14 +161,4 @@ impl VersionedVariant {
151161
}
152162
}
153163
}
154-
155-
pub(crate) fn get_ident(&self, version: &ContainerVersion) -> Option<&syn::Ident> {
156-
match &self.chain {
157-
Some(chain) => chain
158-
.get(&version.inner)
159-
.expect("internal error: chain must contain container version")
160-
.get_ident(),
161-
None => Some(&self.inner.ident),
162-
}
163-
}
164164
}

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ impl Named for Field {
7171
}
7272

7373
impl VersionedField {
74+
/// Creates a new versioned field.
75+
///
76+
/// Internally this calls [`VersionedItem::new`] to handle most of the
77+
/// common creation code.
7478
pub(crate) fn new(
7579
field: Field,
7680
container_attributes: &ContainerAttributes,
@@ -79,6 +83,7 @@ impl VersionedField {
7983
Ok(Self(item))
8084
}
8185

86+
/// Generates tokens to be used in a container definition.
8287
pub(crate) fn generate_for_container(
8388
&self,
8489
container_version: &ContainerVersion,
@@ -95,10 +100,13 @@ impl VersionedField {
95100

96101
let field_type = &self.inner.ty;
97102

98-
match chain
99-
.get(&container_version.inner)
100-
.expect("internal error: chain must contain container version")
101-
{
103+
// NOTE (@Techassi): https://rust-lang.github.io/rust-clippy/master/index.html#/expect_fun_call
104+
match chain.get(&container_version.inner).unwrap_or_else(|| {
105+
panic!(
106+
"internal error: chain must contain container version {}",
107+
container_version.inner
108+
)
109+
}) {
102110
ItemStatus::Added { ident, .. } => Some(quote! {
103111
pub #ident: #field_type,
104112
}),
@@ -133,6 +141,7 @@ impl VersionedField {
133141
}
134142
}
135143

144+
/// Generates tokens to be used in a [`From`] implementation.
136145
pub(crate) fn generate_for_from_impl(
137146
&self,
138147
version: &ContainerVersion,

0 commit comments

Comments
 (0)