Skip to content

Commit 0244a17

Browse files
authored
Merge pull request #580 from swimos/transient-agents
Allows the 'transient' flag to be applied to an entire agent.
2 parents 7496fe2 + 3093612 commit 0244a17

File tree

5 files changed

+70
-12
lines changed

5 files changed

+70
-12
lines changed

macro_utilities/src/names/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ pub enum TypeLevelNameTransform {
6262
Convention(CaseConvention),
6363
}
6464

65+
impl From<CaseConvention> for TypeLevelNameTransform {
66+
fn from(value: CaseConvention) -> Self {
67+
TypeLevelNameTransform::Convention(value)
68+
}
69+
}
70+
71+
impl From<Option<CaseConvention>> for TypeLevelNameTransform {
72+
fn from(value: Option<CaseConvention>) -> Self {
73+
if let Some(conv) = value {
74+
TypeLevelNameTransform::Convention(conv)
75+
} else {
76+
TypeLevelNameTransform::Identity
77+
}
78+
}
79+
}
80+
6581
impl TypeLevelNameTransform {
6682
pub fn is_identity(&self) -> bool {
6783
matches!(self, TypeLevelNameTransform::Identity)

server/swim_agent_derive/src/lane_model_derive/attributes/mod.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ const ROOT_ATTR_NAME: &str = "root";
3232
const INVALID_FIELD_ATTR: &str = "Invalid field attribute.";
3333
const INVALID_AGENT_ROOT: &str = "Invalid agent root specifier.";
3434

35+
struct TransientFlag;
36+
3537
/// Attribute consumer to recognize the transient flag for agent items.
3638
struct TransientFlagConsumer;
3739

@@ -43,14 +45,14 @@ pub enum ItemAttr {
4345
Transform(Transformation),
4446
}
4547

46-
impl NestedMetaConsumer<ItemAttr> for TransientFlagConsumer {
47-
fn try_consume(&self, meta: &syn::NestedMeta) -> Result<Option<ItemAttr>, syn::Error> {
48+
impl NestedMetaConsumer<TransientFlag> for TransientFlagConsumer {
49+
fn try_consume(&self, meta: &syn::NestedMeta) -> Result<Option<TransientFlag>, syn::Error> {
4850
match meta {
4951
syn::NestedMeta::Meta(syn::Meta::Path(path)) => match path.segments.first() {
5052
Some(seg) => {
5153
if seg.ident == TRANSIENT_ATTR_NAME {
5254
if path.segments.len() == 1 && seg.arguments.is_empty() {
53-
Ok(Some(ItemAttr::Transient))
55+
Ok(Some(TransientFlag))
5456
} else {
5557
Err(syn::Error::new_spanned(meta, INVALID_FIELD_ATTR))
5658
}
@@ -68,7 +70,7 @@ impl NestedMetaConsumer<ItemAttr> for TransientFlagConsumer {
6870
pub fn make_item_attr_consumer() -> impl NestedMetaConsumer<ItemAttr> {
6971
let trans_consumer = NameTransformConsumer::new(RENAME_TAG, CONV_TAG);
7072
hlist![
71-
TransientFlagConsumer,
73+
TransientFlagConsumer.map(|_| ItemAttr::Transient),
7274
trans_consumer.map(ItemAttr::Transform)
7375
]
7476
}
@@ -108,6 +110,8 @@ pub fn combine_item_attrs(
108110

109111
/// Types of modification that can be applied to an agent using attributes.
110112
pub enum AgentAttr {
113+
/// Mark all items of the agent as transient.
114+
Transient,
111115
/// Module path where the types from the `swim_agent` create can be found.
112116
Root(syn::Path),
113117
/// Renaming convention to apply to all items of the agent.
@@ -141,6 +145,7 @@ impl NestedMetaConsumer<AgentAttr> for RootConsumer {
141145
pub fn make_agent_attr_consumer() -> impl NestedMetaConsumer<AgentAttr> {
142146
let trans_consumer = TypeLevelNameTransformConsumer::new(CONV_TAG);
143147
hlist![
148+
TransientFlagConsumer.map(|_| AgentAttr::Transient),
144149
RootConsumer,
145150
trans_consumer.map(AgentAttr::RenameConvention)
146151
]
@@ -149,6 +154,8 @@ pub fn make_agent_attr_consumer() -> impl NestedMetaConsumer<AgentAttr> {
149154
/// Modifications to an agent, defined by attributes attached to it.
150155
#[derive(Debug)]
151156
pub struct AgentModifiers {
157+
/// Mark all items of the agent as transient.
158+
pub transient: bool,
152159
/// Renaming strategy for all items of the agent.
153160
pub transform: Option<CaseConvention>,
154161
/// Module path where the types from the `swim_agent` create can be found.
@@ -162,6 +169,7 @@ fn default_root() -> syn::Path {
162169
impl Default for AgentModifiers {
163170
fn default() -> Self {
164171
Self {
172+
transient: false,
165173
transform: None,
166174
root: default_root(),
167175
}
@@ -180,6 +188,7 @@ pub fn combine_agent_attrs(
180188
|mut modifiers, attr| {
181189
let mut errors = Errors::empty();
182190
match attr {
191+
AgentAttr::Transient => modifiers.transient = true,
183192
AgentAttr::Root(path) => modifiers.root = path,
184193
AgentAttr::RenameConvention(conv) => {
185194
if modifiers.transform.is_some() {

server/swim_agent_derive/src/lane_model_derive/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use macro_utilities::TypeLevelNameTransform;
1615
use proc_macro2::TokenStream;
1716
use quote::{quote, ToTokens, TokenStreamExt};
1817
use swim_utilities::errors::{validation::Validation, Errors};
@@ -40,10 +39,12 @@ impl<'a> DeriveAgentLaneModel<'a> {
4039
modifiers: AgentModifiers,
4140
mut model: LanesModel<'a>,
4241
) -> Validation<Self, Errors<syn::Error>> {
43-
let AgentModifiers { transform, root } = modifiers;
44-
if let Some(convention) = transform {
45-
model.apply_transform(TypeLevelNameTransform::Convention(convention));
46-
}
42+
let AgentModifiers {
43+
transient,
44+
transform,
45+
root,
46+
} = modifiers;
47+
model.apply_modifiers(transient, transform.into());
4748
if let Err(err) = model.check_names(src) {
4849
Validation::Validated(DeriveAgentLaneModel { root, model }, Errors::of(err))
4950
} else {

server/swim_agent_derive/src/lane_model_derive/model.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,23 @@ impl<'a> LanesModel<'a> {
4545
LanesModel { agent_type, lanes }
4646
}
4747

48-
/// Apply a name transform to all items.
49-
pub fn apply_transform(&mut self, type_transform: TypeLevelNameTransform) {
50-
for ItemModel { transform, .. } in &mut self.lanes {
48+
/// Apply global transformations to all lanes.
49+
pub fn apply_modifiers(
50+
&mut self,
51+
set_transient_flag: bool,
52+
type_transform: TypeLevelNameTransform,
53+
) {
54+
let add_flags = if set_transient_flag {
55+
ItemFlags::TRANSIENT
56+
} else {
57+
ItemFlags::empty()
58+
};
59+
for ItemModel {
60+
transform, flags, ..
61+
} in &mut self.lanes
62+
{
5163
*transform = type_transform.resolve(std::mem::take(transform));
64+
flags.insert(add_flags);
5265
}
5366
}
5467

swim/tests/deriveagentlanemodel.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,3 +737,22 @@ fn override_top_level_convention() {
737737
persistent_lane_renamed(2, "thirdLane", "third_lane", WarpLaneKind::Value),
738738
]);
739739
}
740+
741+
#[test]
742+
fn agent_level_transient_flag() {
743+
#[derive(AgentLaneModel)]
744+
#[agent(transient)]
745+
struct EverythingTransient {
746+
first: ValueLane<i32>,
747+
second: MapLane<i32, i32>,
748+
third: CommandLane<i32>,
749+
fourth: ValueStore<i32>,
750+
}
751+
752+
check_agent::<EverythingTransient>(vec![
753+
transient_lane(0, "first", WarpLaneKind::Value),
754+
transient_lane(1, "second", WarpLaneKind::Map),
755+
transient_lane(2, "third", WarpLaneKind::Command),
756+
transient_store(3, "fourth", StoreKind::Value),
757+
]);
758+
}

0 commit comments

Comments
 (0)