Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stackable-versioned): Forward container visibility #850

Merged
merged 3 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions crates/stackable-versioned-macros/src/codegen/common/container.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::ops::Deref;

use proc_macro2::TokenStream;
use syn::{Attribute, Ident};
use syn::{Attribute, Ident, Visibility};

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

Expand All @@ -21,12 +21,7 @@ where
Self: Sized + Deref<Target = VersionedContainer<I>>,
{
/// Creates a new versioned container.
fn new(
ident: Ident,
data: D,
attributes: ContainerAttributes,
original_attributes: Vec<Attribute>,
) -> syn::Result<Self>;
fn new(input: ContainerInput, data: D, attributes: ContainerAttributes) -> syn::Result<Self>;

/// This generates the complete code for a single versioned container.
///
Expand All @@ -37,6 +32,21 @@ where
fn generate_tokens(&self) -> TokenStream;
}

/// This struct bundles values from [`DeriveInput`][1].
///
/// [`DeriveInput`][1] cannot be used directly when constructing a
/// [`VersionedStruct`][2] or [`VersionedEnum`][3] because we run into borrow
/// issues caused by the match statement which extracts the data.
///
/// [1]: syn::DeriveInput
/// [2]: crate::codegen::vstruct::VersionedStruct
/// [3]: crate::codegen::venum::VersionedEnum
pub(crate) struct ContainerInput {
pub(crate) original_attributes: Vec<Attribute>,
pub(crate) visibility: Visibility,
pub(crate) ident: Ident,
}

/// Stores individual versions of a single container.
///
/// Each version tracks item actions, which describe if the item was added,
Expand All @@ -55,13 +65,17 @@ pub(crate) struct VersionedContainer<I> {
/// The ident, or name, of the versioned container.
pub(crate) ident: Ident,

/// The visibility of the versioned container. Used to forward the
/// visibility during code generation.
pub(crate) visibility: Visibility,

/// The original attributes that were added to the container.
pub(crate) original_attributes: Vec<Attribute>,

/// The name of the container used in `From` implementations.
pub(crate) from_ident: Ident,

/// Whether the [`From`] implementation generation should be skipped for all
/// versions of this container.
pub(crate) skip_from: bool,

/// The original attributes that were added to the container.
pub(crate) original_attributes: Vec<Attribute>,
}
22 changes: 19 additions & 3 deletions crates/stackable-versioned-macros/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use syn::{spanned::Spanned, Data, DeriveInput, Error, Result};

use crate::{
attrs::common::ContainerAttributes,
codegen::{common::Container, venum::VersionedEnum, vstruct::VersionedStruct},
codegen::{
common::{Container, ContainerInput},
venum::VersionedEnum,
vstruct::VersionedStruct,
},
};

pub(crate) mod chain;
Expand All @@ -26,10 +30,22 @@ pub(crate) mod vstruct;
pub(crate) fn expand(attributes: ContainerAttributes, input: DeriveInput) -> Result<TokenStream> {
let expanded = match input.data {
Data::Struct(data) => {
VersionedStruct::new(input.ident, data, attributes, input.attrs)?.generate_tokens()
let input = ContainerInput {
original_attributes: input.attrs,
visibility: input.vis,
ident: input.ident,
};

VersionedStruct::new(input, data, attributes)?.generate_tokens()
}
Data::Enum(data) => {
VersionedEnum::new(input.ident, data, attributes, input.attrs)?.generate_tokens()
let input = ContainerInput {
original_attributes: input.attrs,
visibility: input.vis,
ident: input.ident,
};

VersionedEnum::new(input, data, attributes)?.generate_tokens()
}
_ => {
return Err(Error::new(
Expand Down
23 changes: 16 additions & 7 deletions crates/stackable-versioned-macros/src/codegen/venum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use std::ops::Deref;
use itertools::Itertools;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Attribute, DataEnum, Error, Ident};
use syn::{DataEnum, Error};

use crate::{
attrs::common::ContainerAttributes,
codegen::{
common::{
format_container_from_ident, Container, ContainerVersion, Item, VersionedContainer,
format_container_from_ident, Container, ContainerInput, ContainerVersion, Item,
VersionedContainer,
},
venum::variant::VersionedVariant,
},
Expand All @@ -34,11 +35,16 @@ impl Deref for VersionedEnum {

impl Container<DataEnum, VersionedVariant> for VersionedEnum {
fn new(
ident: Ident,
input: ContainerInput,
data: DataEnum,
attributes: ContainerAttributes,
original_attributes: Vec<Attribute>,
) -> syn::Result<Self> {
let ContainerInput {
original_attributes,
visibility,
ident,
} = input;

// Convert the raw version attributes into a container version.
let versions: Vec<_> = (&attributes).into();

Expand Down Expand Up @@ -78,11 +84,12 @@ impl Container<DataEnum, VersionedVariant> for VersionedEnum {
.options
.skip
.map_or(false, |s| s.from.is_present()),
original_attributes,
visibility,
from_ident,
versions,
items,
ident,
original_attributes,
}))
}

Expand All @@ -105,8 +112,10 @@ impl VersionedEnum {
next_version: Option<&ContainerVersion>,
) -> TokenStream {
let mut token_stream = TokenStream::new();
let enum_name = &self.ident;

let original_attributes = &self.original_attributes;
let visibility = &self.visibility;
let enum_name = &self.ident;

// Generate variants of the enum for `version`.
let variants = self.generate_enum_variants(version);
Expand Down Expand Up @@ -140,7 +149,7 @@ impl VersionedEnum {
token_stream.extend(quote! {
#[automatically_derived]
#deprecated_attr
pub mod #version_ident {
#visibility mod #version_ident {
#(#original_attributes)*
#version_specific_docs
pub enum #enum_name {
Expand Down
23 changes: 16 additions & 7 deletions crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use std::ops::Deref;
use itertools::Itertools;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Attribute, DataStruct, Error, Ident};
use syn::{DataStruct, Error, Ident};

use crate::{
attrs::common::ContainerAttributes,
codegen::{
common::{
format_container_from_ident, Container, ContainerVersion, Item, VersionedContainer,
format_container_from_ident, Container, ContainerInput, ContainerVersion, Item,
VersionedContainer,
},
vstruct::field::VersionedField,
},
Expand All @@ -34,11 +35,16 @@ impl Deref for VersionedStruct {

impl Container<DataStruct, VersionedField> for VersionedStruct {
fn new(
ident: Ident,
input: ContainerInput,
data: DataStruct,
attributes: ContainerAttributes,
original_attributes: Vec<Attribute>,
) -> syn::Result<Self> {
let ContainerInput {
original_attributes,
visibility,
ident,
} = input;

// Convert the raw version attributes into a container version.
let versions: Vec<_> = (&attributes).into();

Expand Down Expand Up @@ -78,11 +84,12 @@ impl Container<DataStruct, VersionedField> for VersionedStruct {
.options
.skip
.map_or(false, |s| s.from.is_present()),
original_attributes,
visibility,
from_ident,
versions,
items,
ident,
original_attributes,
}))
}

Expand All @@ -105,8 +112,10 @@ impl VersionedStruct {
next_version: Option<&ContainerVersion>,
) -> TokenStream {
let mut token_stream = TokenStream::new();
let struct_name = &self.ident;

let original_attributes = &self.original_attributes;
let visibility = &self.visibility;
let struct_name = &self.ident;

// Generate fields of the struct for `version`.
let fields = self.generate_struct_fields(version);
Expand Down Expand Up @@ -140,7 +149,7 @@ impl VersionedStruct {
token_stream.extend(quote! {
#[automatically_derived]
#deprecated_attr
pub mod #version_ident {
#visibility mod #version_ident {
#(#original_attributes)*
#version_specific_docs
pub struct #struct_name {
Expand Down
4 changes: 3 additions & 1 deletion crates/stackable-versioned/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ All notable changes to this project will be documented in this file.
### Added

- Pass through container and item attributes (including doc-comments). Add
attribute for version specific docs. ([#847])
attribute for version specific docs ([#847]).
- Forward container visibility to generated modules ([#850]).

### Fixed

Expand All @@ -16,6 +17,7 @@ All notable changes to this project will be documented in this file.

[#842]: https://github.com/stackabletech/operator-rs/pull/842
[#847]: https://github.com/stackabletech/operator-rs/pull/847
[#850]: https://github.com/stackabletech/operator-rs/pull/850

## [0.1.1] - 2024-07-10

Expand Down
Loading