Compare commits
7 Commits
v0.3.0
...
ece96ac4e5
| Author | SHA1 | Date | |
|---|---|---|---|
| ece96ac4e5 | |||
| eadfb8db23 | |||
| 784605c418 | |||
| de53d000e8 | |||
| 31dfb00c51 | |||
| 6233a3a0b7 | |||
| d98d0bc34c |
@@ -13,7 +13,7 @@ categories.workspace = true
|
|||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.2.1"
|
version = "0.4.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.81"
|
rust-version = "1.81"
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ categories = ["api-bindings"]
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aws-macros = { path = "./aws_macros", version = "0.2.*" }
|
aws-macros = { path = "./aws_macros", version = "0.4.*" }
|
||||||
aws-config = { version = "1.*", default-features = false }
|
aws-config = { version = "1.*", default-features = false }
|
||||||
aws-sdk-ec2 = { version = "1.*", default-features = false, features = [
|
aws-sdk-ec2 = { version = "1.*", default-features = false, features = [
|
||||||
"rustls",
|
"rustls",
|
||||||
|
|||||||
5
Makefile
5
Makefile
@@ -7,11 +7,12 @@ docs:
|
|||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
@cargo test --workspace --color=always
|
cargo hack --feature-powerset --no-dev-deps check
|
||||||
|
cargo test --workspace --color=always
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint:
|
lint:
|
||||||
@cargo clippy --workspace --tests --color=always
|
cargo clippy --workspace --tests --color=always
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# AWS
|
# AWS
|
||||||
|
|
||||||
* Helper functions for frequently used AWS operations (create EC2 instance, Route53 record, ...)
|
- Helper functions for frequently used AWS operations (create EC2 instance,
|
||||||
* Type-safe operations on AWS tags (e.g. from an EC2 instance), see [the separate README](./src/tags/README.md)
|
Route53 record, ...)
|
||||||
|
- Type-safe operations on AWS tags (e.g. from an EC2 instance), see
|
||||||
|
[the separate README](./src/tags/README.md)
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ syn = { version = "2.*", default-features = false, features = [
|
|||||||
"parsing",
|
"parsing",
|
||||||
"printing",
|
"printing",
|
||||||
"clone-impls",
|
"clone-impls",
|
||||||
|
"derive",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ pub fn Tags(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
tags::transform(attr, item)
|
tags::transform(attr, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_derive(Tag, attributes(tag))]
|
||||||
#[expect(non_snake_case, reason = "attribute proc macros should be capitalized")]
|
pub fn tag(input: TokenStream) -> TokenStream {
|
||||||
pub fn Tag(attr: TokenStream, item: TokenStream) -> TokenStream {
|
tag::transform(input)
|
||||||
tag::transform(attr, item)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,22 +18,14 @@ enum Translator {
|
|||||||
Transparent(TransparentKind),
|
Transparent(TransparentKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_enum_attributes(attrs: &mut Vec<syn::Attribute>) -> Option<syn::LitStr> {
|
fn parse_enum_attributes(attrs: &[syn::Attribute]) -> Option<syn::LitStr> {
|
||||||
let index_of_tag_attribute = attrs
|
let index_of_tag_attribute = attrs
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.filter(|attr| attr.style == syn::AttrStyle::Outer)
|
||||||
.filter(|&(_i, attr)| attr.style == syn::AttrStyle::Outer)
|
.find_map(|attr| match attr.meta {
|
||||||
.find_map(|(i, attr)| match attr.meta {
|
|
||||||
syn::Meta::List(ref meta_list) => {
|
syn::Meta::List(ref meta_list) => {
|
||||||
if let (Some(name), 1) = (
|
if meta_list.path.is_ident("tag") {
|
||||||
meta_list.path.segments.first(),
|
Some(meta_list.clone())
|
||||||
meta_list.path.segments.len(),
|
|
||||||
) {
|
|
||||||
if name.ident == "tag" {
|
|
||||||
Some((i, meta_list.clone()))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -42,11 +34,7 @@ fn parse_enum_attributes(attrs: &mut Vec<syn::Attribute>) -> Option<syn::LitStr>
|
|||||||
});
|
});
|
||||||
|
|
||||||
match index_of_tag_attribute {
|
match index_of_tag_attribute {
|
||||||
Some((i, meta_list)) => {
|
Some(meta_list) => {
|
||||||
// `i` came from `enumerate()` and is guaranteed to be in bounds
|
|
||||||
let removed_attribute = attrs.remove(i);
|
|
||||||
drop(removed_attribute);
|
|
||||||
|
|
||||||
let expr: syn::Expr =
|
let expr: syn::Expr =
|
||||||
syn::parse(meta_list.tokens.into()).expect("expected expr in macro attribute");
|
syn::parse(meta_list.tokens.into()).expect("expected expr in macro attribute");
|
||||||
|
|
||||||
@@ -54,12 +42,7 @@ fn parse_enum_attributes(attrs: &mut Vec<syn::Attribute>) -> Option<syn::LitStr>
|
|||||||
syn::Expr::Assign(ref assign) => {
|
syn::Expr::Assign(ref assign) => {
|
||||||
match *assign.left {
|
match *assign.left {
|
||||||
syn::Expr::Path(ref exprpath) => {
|
syn::Expr::Path(ref exprpath) => {
|
||||||
let segments = &exprpath.path.segments;
|
assert!(exprpath.path.is_ident("rename"), "invalid attribute key");
|
||||||
let (Some(segment), 1) = (segments.first(), segments.len()) else {
|
|
||||||
panic!("invalid attribute key")
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(segment.ident == "rename", "invalid attribute key");
|
|
||||||
}
|
}
|
||||||
_ => panic!("invalid expression in enum variant attribute, left side"),
|
_ => panic!("invalid expression in enum variant attribute, left side"),
|
||||||
}
|
}
|
||||||
@@ -79,10 +62,10 @@ fn parse_enum_attributes(attrs: &mut Vec<syn::Attribute>) -> Option<syn::LitStr>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_transparent_enum(mut e: syn::ItemEnum) -> (Translator, syn::Item) {
|
fn parse_transparent_enum(e: &syn::DataEnum) -> Translator {
|
||||||
let variants = e
|
let variants = e
|
||||||
.variants
|
.variants
|
||||||
.iter_mut()
|
.iter()
|
||||||
.map(|variant| {
|
.map(|variant| {
|
||||||
assert!(
|
assert!(
|
||||||
variant.discriminant.is_none(),
|
variant.discriminant.is_none(),
|
||||||
@@ -92,88 +75,99 @@ fn parse_transparent_enum(mut e: syn::ItemEnum) -> (Translator, syn::Item) {
|
|||||||
syn::Fields::Unit => (),
|
syn::Fields::Unit => (),
|
||||||
_ => panic!("enum cannot have fields in variants"),
|
_ => panic!("enum cannot have fields in variants"),
|
||||||
}
|
}
|
||||||
let rename = parse_enum_attributes(&mut variant.attrs);
|
let rename = parse_enum_attributes(&variant.attrs);
|
||||||
|
|
||||||
(variant.ident.clone(), rename)
|
(variant.ident.clone(), rename)
|
||||||
})
|
})
|
||||||
.collect::<Vec<(syn::Ident, Option<syn::LitStr>)>>();
|
.collect::<Vec<(syn::Ident, Option<syn::LitStr>)>>();
|
||||||
|
|
||||||
(
|
Translator::Transparent(TransparentKind::SimpleEnum { variants })
|
||||||
Translator::Transparent(TransparentKind::SimpleEnum { variants }),
|
|
||||||
e.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn transform(attr: TokenStream, item: TokenStream) -> TokenStream {
|
fn parse_tag_attribute(expr: syn::Expr, elem: &syn::Data) -> Translator {
|
||||||
let root = quote! {::aws_lib};
|
|
||||||
|
|
||||||
let expr: syn::Expr = syn::parse(attr).expect("expected expr in macro attribute");
|
|
||||||
|
|
||||||
let elem = syn::parse_macro_input!(item as syn::Item);
|
|
||||||
|
|
||||||
let syn::Expr::Assign(assign) = expr else {
|
let syn::Expr::Assign(assign) = expr else {
|
||||||
panic!("invalid expression in macro attribute")
|
panic!("invalid expression in macro attribute")
|
||||||
};
|
};
|
||||||
|
|
||||||
match *assign.left {
|
match *assign.left {
|
||||||
syn::Expr::Path(ref exprpath) => {
|
syn::Expr::Path(ref exprpath) => {
|
||||||
let segments = &exprpath.path.segments;
|
assert!(exprpath.path.is_ident("translate"), "invalid attribute key");
|
||||||
let (Some(segment), 1) = (segments.first(), segments.len()) else {
|
|
||||||
panic!("invalid attribute key")
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(segment.ident == "translate", "invalid attribute key");
|
|
||||||
}
|
}
|
||||||
_ => panic!("invalid expression in tag field attribute, left side"),
|
_ => panic!("invalid expression in tag field attribute, left side"),
|
||||||
}
|
}
|
||||||
|
|
||||||
let (translator, elem) = match *assign.right {
|
match *assign.right {
|
||||||
syn::Expr::Path(ref exprpath) => {
|
syn::Expr::Path(ref exprpath) => {
|
||||||
let segments = &exprpath.path.segments;
|
let Some(ident) = exprpath.path.get_ident() else {
|
||||||
let (Some(segment), 1) = (segments.first(), segments.len()) else {
|
|
||||||
panic!("invalid attribute key")
|
panic!("invalid attribute key")
|
||||||
};
|
};
|
||||||
|
|
||||||
match segment.ident.to_string().as_str() {
|
match ident.to_string().as_str() {
|
||||||
"serde" => (Translator::Serde, elem),
|
"serde" => Translator::Serde,
|
||||||
"manual" => (Translator::Manual, elem),
|
"manual" => Translator::Manual,
|
||||||
"transparent" => match elem {
|
"transparent" =>
|
||||||
syn::Item::Struct(ref s) => match s.fields {
|
{
|
||||||
syn::Fields::Unnamed(ref fields) => {
|
#[expect(
|
||||||
let (Some(field), 1) = (fields.unnamed.first(), fields.unnamed.len())
|
clippy::match_wildcard_for_single_variants,
|
||||||
else {
|
reason = "just by chance is there only one additional variant"
|
||||||
panic!(
|
)]
|
||||||
"transparent translation is only available for newtype-style macros"
|
match *elem {
|
||||||
)
|
syn::Data::Struct(ref s) => match s.fields {
|
||||||
};
|
syn::Fields::Unnamed(ref fields) => {
|
||||||
(
|
let (Some(field), 1) =
|
||||||
|
(fields.unnamed.first(), fields.unnamed.len())
|
||||||
|
else {
|
||||||
|
panic!(
|
||||||
|
"transparent translation is only available for newtype-style macros"
|
||||||
|
)
|
||||||
|
};
|
||||||
Translator::Transparent(TransparentKind::NewtypeStruct {
|
Translator::Transparent(TransparentKind::NewtypeStruct {
|
||||||
ty: field.ty.clone(),
|
ty: field.ty.clone(),
|
||||||
}),
|
})
|
||||||
elem,
|
}
|
||||||
)
|
_ => panic!(
|
||||||
|
"transparent translation is only available for newtype-style macros"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
syn::Data::Enum(ref e) => parse_transparent_enum(e),
|
||||||
|
_ => {
|
||||||
|
panic!("transparent translation is only available for newtype-style macros")
|
||||||
}
|
}
|
||||||
_ => panic!(
|
|
||||||
"transparent translation is only available for newtype-style macros"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
syn::Item::Enum(e) => parse_transparent_enum(e),
|
|
||||||
_ => {
|
|
||||||
panic!("transparent translation is only available for newtype-style macros")
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
t => panic!("invalid translator {t}"),
|
t => panic!("invalid translator {t}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => panic!("invalid expression in tag field attribute, left side"),
|
_ => panic!("invalid expression in tag field attribute, left side"),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let name = match elem {
|
pub(crate) fn transform(input: TokenStream) -> TokenStream {
|
||||||
syn::Item::Struct(ref s) => &s.ident,
|
let root = quote! {::aws_lib};
|
||||||
syn::Item::Enum(ref e) => &e.ident,
|
|
||||||
_ => panic!("only applicable to structs/enums"),
|
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||||
};
|
|
||||||
|
let expr = input
|
||||||
|
.attrs
|
||||||
|
.into_iter()
|
||||||
|
.find_map(|attr| match attr.meta {
|
||||||
|
syn::Meta::List(meta_list) => {
|
||||||
|
if meta_list.path.is_ident("tag") {
|
||||||
|
Some(
|
||||||
|
syn::parse2::<syn::Expr>(meta_list.tokens)
|
||||||
|
.expect("invalid expression in tag attribute"),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.expect("Tag derive macro requires a tag attribute");
|
||||||
|
|
||||||
|
let translator = parse_tag_attribute(expr, &input.data);
|
||||||
|
|
||||||
|
let name = input.ident;
|
||||||
|
|
||||||
let translator = match translator {
|
let translator = match translator {
|
||||||
Translator::Serde => quote! {
|
Translator::Serde => quote! {
|
||||||
@@ -271,7 +265,6 @@ pub(crate) fn transform(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#elem
|
|
||||||
#translator
|
#translator
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
|
|||||||
@@ -24,6 +24,19 @@ struct Element {
|
|||||||
attrs: Vec<syn::Attribute>,
|
attrs: Vec<syn::Attribute>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_cfg_attribute(attr: &syn::Attribute) -> bool {
|
||||||
|
match attr.meta {
|
||||||
|
syn::Meta::List(ref meta_list) => meta_list.path.is_ident("cfg"),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cfg_attrs(v: &[syn::Attribute]) -> Vec<&syn::Attribute> {
|
||||||
|
v.iter()
|
||||||
|
.filter(|attr: &&syn::Attribute| is_cfg_attribute(attr))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_type(input: syn::Type) -> (syn::Path, ElementKind) {
|
fn parse_type(input: syn::Type) -> (syn::Path, ElementKind) {
|
||||||
match input {
|
match input {
|
||||||
syn::Type::Path(ty) => {
|
syn::Type::Path(ty) => {
|
||||||
@@ -74,13 +87,8 @@ fn parse_field_attrs(attrs: &mut Vec<syn::Attribute>) -> Option<String> {
|
|||||||
.filter(|&(_i, attr)| attr.style == syn::AttrStyle::Outer)
|
.filter(|&(_i, attr)| attr.style == syn::AttrStyle::Outer)
|
||||||
.find_map(|(i, attr)| match attr.meta {
|
.find_map(|(i, attr)| match attr.meta {
|
||||||
syn::Meta::List(ref meta_list) => {
|
syn::Meta::List(ref meta_list) => {
|
||||||
let tag = &meta_list.path;
|
if meta_list.path.is_ident("tag") {
|
||||||
if let (Some(segment), 1) = (tag.segments.first(), tag.segments.len()) {
|
Some((i, meta_list.clone()))
|
||||||
if segment.ident == "tag" {
|
|
||||||
Some((i, meta_list.clone()))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -104,12 +112,10 @@ fn parse_field_attrs(attrs: &mut Vec<syn::Attribute>) -> Option<String> {
|
|||||||
|
|
||||||
match *assign.left {
|
match *assign.left {
|
||||||
syn::Expr::Path(ref exprpath) => {
|
syn::Expr::Path(ref exprpath) => {
|
||||||
let segments = &exprpath.path.segments;
|
assert!(
|
||||||
let (Some(segment), 1) = (segments.first(), segments.len()) else {
|
exprpath.path.is_ident("key"),
|
||||||
panic!("invalid tag field attribute key")
|
"invalid tag field attribute key"
|
||||||
};
|
);
|
||||||
|
|
||||||
assert!(segment.ident == "key", "invalid tag field attribute key");
|
|
||||||
}
|
}
|
||||||
_ => panic!("invalid expression in tag field attribute, left side"),
|
_ => panic!("invalid expression in tag field attribute, left side"),
|
||||||
}
|
}
|
||||||
@@ -203,7 +209,7 @@ fn build_output(input: Input) -> TokenStream {
|
|||||||
let params = input.elements.iter().map(|element| {
|
let params = input.elements.iter().map(|element| {
|
||||||
let ident = &element.ident;
|
let ident = &element.ident;
|
||||||
let ty = &element.ty;
|
let ty = &element.ty;
|
||||||
let attrs = &element.attrs;
|
let attrs = cfg_attrs(&element.attrs);
|
||||||
match element.kind {
|
match element.kind {
|
||||||
ElementKind::Required => quote! {
|
ElementKind::Required => quote! {
|
||||||
#(#attrs)
|
#(#attrs)
|
||||||
@@ -223,7 +229,7 @@ fn build_output(input: Input) -> TokenStream {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|element| {
|
.map(|element| {
|
||||||
let ident = &element.ident;
|
let ident = &element.ident;
|
||||||
let attrs = &element.attrs;
|
let attrs = cfg_attrs(&element.attrs);
|
||||||
quote! {
|
quote! {
|
||||||
#(#attrs)
|
#(#attrs)
|
||||||
*
|
*
|
||||||
@@ -232,11 +238,11 @@ fn build_output(input: Input) -> TokenStream {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let from_tags_fields: Vec<proc_macro2::TokenStream>= input.elements.iter().map(|element| {
|
let from_tags_fields: Vec<proc_macro2::TokenStream> = input.elements.iter().map(|element| {
|
||||||
let ident = &element.ident;
|
let ident = &element.ident;
|
||||||
let ty = &element.ty;
|
let ty = &element.ty;
|
||||||
let tag_name = &element.name;
|
let tag_name = &element.name;
|
||||||
let attrs = &element.attrs;
|
let attrs = cfg_attrs(&element.attrs);
|
||||||
|
|
||||||
let try_convert = quote! {
|
let try_convert = quote! {
|
||||||
let value: ::std::result::Result<#ty, #root::tags::ParseTagsError> = <#ty as #root::tags::TagValue<#ty>>::from_raw_tag(value)
|
let value: ::std::result::Result<#ty, #root::tags::ParseTagsError> = <#ty as #root::tags::TagValue<#ty>>::from_raw_tag(value)
|
||||||
|
|||||||
@@ -337,9 +337,9 @@ impl fmt::Display for SubnetId {
|
|||||||
|
|
||||||
macro_rules! string_newtype {
|
macro_rules! string_newtype {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
#[Tag(translate = transparent)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq, Tag)]
|
||||||
|
#[tag(translate = transparent)]
|
||||||
pub struct $name(String);
|
pub struct $name(String);
|
||||||
|
|
||||||
impl std::fmt::Display for $name {
|
impl std::fmt::Display for $name {
|
||||||
@@ -422,9 +422,9 @@ impl TryFrom<aws_sdk_ec2::types::Image> for Ami {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Tag(translate = manual)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
|
#[derive(Tag, Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
|
||||||
|
#[tag(translate = manual)]
|
||||||
pub struct Timestamp(DateTime<Utc>);
|
pub struct Timestamp(DateTime<Utc>);
|
||||||
|
|
||||||
impl Timestamp {
|
impl Timestamp {
|
||||||
|
|||||||
@@ -51,14 +51,14 @@ strategies:
|
|||||||
- `impl From<T> for RawTagValue`: How to turn `T` back into the value of a
|
- `impl From<T> for RawTagValue`: How to turn `T` back into the value of a
|
||||||
tag. This cannot fail.
|
tag. This cannot fail.
|
||||||
|
|
||||||
There is a [`macro@Tag`] macro that selects the strategy, which can then be used
|
There is a [`macro@Tag`] derive macro that selects the strategy, which can then
|
||||||
in a struct that is using `#[Tags]`:
|
be used in a struct that is using `#[Tags]`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use aws_lib::tags::{Tag, Tags};
|
use aws_lib::tags::{Tag, Tags};
|
||||||
|
|
||||||
#[Tag(translate = transparent)]
|
#[derive(Tag, Debug, Clone, PartialEq, Eq)]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[tag(translate = transparent)]
|
||||||
struct MyTag(String);
|
struct MyTag(String);
|
||||||
|
|
||||||
#[Tags]
|
#[Tags]
|
||||||
|
|||||||
@@ -309,16 +309,16 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[Tag(translate = manual)]
|
#[derive(Tag, Debug, Clone, PartialEq, Eq)]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[tag(translate = manual)]
|
||||||
enum MyTag {
|
enum MyTag {
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-tags")]
|
#[cfg(feature = "serde-tags")]
|
||||||
#[Tag(translate = serde)]
|
#[derive(Tag, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[tag(translate = serde)]
|
||||||
struct MyStructTag {
|
struct MyStructTag {
|
||||||
foo: String,
|
foo: String,
|
||||||
bar: bool,
|
bar: bool,
|
||||||
@@ -426,8 +426,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transparent_tag() {
|
fn test_transparent_tag() {
|
||||||
#[Tag(translate = transparent)]
|
#[derive(Tag, PartialEq, Debug)]
|
||||||
#[derive(PartialEq, Debug)]
|
#[tag(translate = transparent)]
|
||||||
struct MyTag(String);
|
struct MyTag(String);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -442,8 +442,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_enums() {
|
fn test_enums() {
|
||||||
#[Tag(translate = transparent)]
|
#[derive(PartialEq, Debug, Tag)]
|
||||||
#[derive(PartialEq, Debug)]
|
#[tag(translate = transparent)]
|
||||||
enum MyCoolioTag {
|
enum MyCoolioTag {
|
||||||
A,
|
A,
|
||||||
#[tag(rename = "C")]
|
#[tag(rename = "C")]
|
||||||
|
|||||||
Reference in New Issue
Block a user