diff --git a/Cargo.lock b/Cargo.lock index ab3b242..af909db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -755,7 +755,7 @@ dependencies = [ [[package]] name = "dropshot-authorization-header" -version = "0.4.1" +version = "0.4.2" dependencies = [ "async-trait", "base64", @@ -3538,7 +3538,7 @@ dependencies = [ [[package]] name = "v-api" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-trait", @@ -3586,7 +3586,7 @@ dependencies = [ [[package]] name = "v-api-param" -version = "0.4.1" +version = "0.4.2" dependencies = [ "secrecy", "serde", @@ -3597,7 +3597,7 @@ dependencies = [ [[package]] name = "v-api-permission-derive" -version = "0.4.1" +version = "0.4.2" dependencies = [ "heck", "newtype-uuid", @@ -3614,7 +3614,7 @@ dependencies = [ [[package]] name = "v-cli-sdk" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "clap", @@ -3636,7 +3636,7 @@ dependencies = [ [[package]] name = "v-model" -version = "0.4.1" +version = "0.4.2" dependencies = [ "async-bb8-diesel", "async-trait", @@ -4230,7 +4230,7 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xtask" -version = "0.4.1" +version = "0.4.2" dependencies = [ "clap", "regex", diff --git a/Cargo.toml b/Cargo.toml index cbdbf6d..e93f36b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ resolver = "2" [workspace.package] publish = true edition = "2024" -version = "0.4.1" +version = "0.4.2" [workspace.dependencies] anyhow = "1.0" diff --git a/v-api-permission-derive/src/lib.rs b/v-api-permission-derive/src/lib.rs index b16694c..7be00df 100644 --- a/v-api-permission-derive/src/lib.rs +++ b/v-api-permission-derive/src/lib.rs @@ -1008,11 +1008,27 @@ fn permission_storage_contract_tokens( }; match setting.kind { - ContractKind::Append => branches.push(quote! { - #permission_type::#variant_ident(#fields) => { - #set_name.insert(*#fields); - } - }), + ContractKind::Append => { + assert_eq!( + variant.fields.len(), + 1, + "contract(kind = append) requires exactly one field on variant `{}`", + variant_ident, + ); + let field_ident = variant + .fields + .iter() + .next() + .unwrap() + .ident + .as_ref() + .unwrap_or(&stock_field_names[0]); + branches.push(quote! { + #permission_type::#variant_ident(#field_ident) => { + #set_name.insert(#field_ident.clone()); + } + }); + } ContractKind::Drop => { // We are dropping the specific permission value } @@ -1118,7 +1134,7 @@ fn permission_storage_expand_tokens( quote! { #permission_type::#variant_ident => { for f0 in &#source.#field { - expanded.push(#permission_type::#target_variant(*f0)) + expanded.push(#permission_type::#target_variant(f0.clone())) } } } @@ -1129,7 +1145,7 @@ fn permission_storage_expand_tokens( quote! { #permission_type::#variant_ident(field) => { for f0 in field { - expanded.push(#permission_type::#target_variant(*f0)) + expanded.push(#permission_type::#target_variant(f0.clone())) } } } @@ -1145,7 +1161,7 @@ fn permission_storage_expand_tokens( ExternalSource::Actor => { let source = source.to_ident(); quote! { - #permission_type::#variant_ident => expanded.push(#permission_type::#target_variant(#source.#field)), + #permission_type::#variant_ident => expanded.push(#permission_type::#target_variant(#source.#field.clone())), } }, ExternalSource::Extension => { @@ -1158,7 +1174,7 @@ fn permission_storage_expand_tokens( use std::any::Any; let entry: Option<&#ext> = (**entry).downcast_ref(); if let Some(entry) = entry { - expanded.push(#permission_type::#target_variant(entry.#field)); + expanded.push(#permission_type::#target_variant(entry.#field.clone())); } } }, diff --git a/v-api-permission-derive/tests/derive.rs b/v-api-permission-derive/tests/derive.rs index 04a6546..d4a13bc 100644 --- a/v-api-permission-derive/tests/derive.rs +++ b/v-api-permission-derive/tests/derive.rs @@ -50,6 +50,10 @@ enum AppPermissions { Flip(TypedUuid), #[v_api(expand(kind = replace, variant = Flip, source = actor, field = id))] Flop, + #[v_api(contract(kind = append, variant = NonCopies))] + NonCopy(String), + #[v_api(expand(kind = iter, variant = NonCopy))] + NonCopies(BTreeSet), } #[test]