diff --git a/README.md b/README.md
index 08c21cb6..9f321b6e 100644
--- a/README.md
+++ b/README.md
@@ -721,6 +721,33 @@ struct TestTypeA {
```
+
+
+
+Renaming fields |
+
+
+```asn
+Test-type-a ::= SEQUENCE {
+ notQuiteRustCase INTEGER
+}
+```
+
+ |
+
+
+```rust
+use rasn::prelude::*;
+
+#[derive(AsnType, Decode, Encode)]
+#[rasn(automatic_tags, identifier = "Test-type-a")]
+struct TestTypeA {
+ #[rasn(identifier = "notQuiteRustCase")]
+ rust_case_indeed: Integer
+}
+
+```
+
|
diff --git a/macros/src/asn_type.rs b/macros/src/asn_type.rs
index dd71f516..e26deafd 100644
--- a/macros/src/asn_type.rs
+++ b/macros/src/asn_type.rs
@@ -94,6 +94,11 @@ pub fn derive_struct_impl(
let constraints_def = config.constraints.const_static_def(crate_root);
+ let alt_identifier = config.identifier.as_ref().map_or(
+ quote!(),
+ |id| quote!(const IDENTIFIER: Option<&'static str> = Some(#id);),
+ );
+
quote! {
#constructed_impl
@@ -104,7 +109,7 @@ pub fn derive_struct_impl(
#tag
};
-
+ #alt_identifier
#constraints_def
}
}
diff --git a/macros/src/config.rs b/macros/src/config.rs
index a17d3c57..3a257234 100644
--- a/macros/src/config.rs
+++ b/macros/src/config.rs
@@ -1,7 +1,7 @@
use std::ops::Deref;
use quote::ToTokens;
-use syn::{Lit, NestedMeta, Path, UnOp};
+use syn::{Lit, LitStr, NestedMeta, Path, UnOp};
use crate::{ext::TypeExt, tag::Tag};
@@ -214,6 +214,7 @@ impl Constraints {
#[derive(Clone, Debug)]
pub struct Config {
pub crate_root: Path,
+ pub identifier: Option,
pub enumerated: bool,
pub choice: bool,
pub set: bool,
@@ -229,6 +230,7 @@ impl Config {
let mut choice = false;
let mut set = false;
let mut crate_root = None;
+ let mut identifier = None;
let mut enumerated = false;
let mut automatic_tags = false;
let mut tag = None;
@@ -262,6 +264,13 @@ impl Config {
_ => None,
};
}
+ } else if path.is_ident("identifier") {
+ if let syn::Meta::NameValue(nv) = item {
+ identifier = match &nv.lit {
+ syn::Lit::Str(s) => Some(s.clone()),
+ _ => None,
+ };
+ }
} else if path.is_ident("enumerated") {
enumerated = true;
} else if path.is_ident("choice") {
@@ -362,6 +371,7 @@ impl Config {
option_type,
set,
tag,
+ identifier,
constraints: Constraints {
extensible,
from,
@@ -457,6 +467,7 @@ pub struct VariantConfig<'config> {
container_config: &'config Config,
generics: &'config syn::Generics,
pub tag: Option,
+ pub identifier: Option,
pub extension_addition: bool,
pub constraints: Constraints,
}
@@ -468,6 +479,7 @@ impl<'config> VariantConfig<'config> {
container_config: &'config Config,
) -> Self {
let mut extensible = false;
+ let mut identifier = None;
let mut extension_addition = false;
let mut from = None;
let mut size = None;
@@ -488,6 +500,13 @@ impl<'config> VariantConfig<'config> {
let path = item.path();
if path.is_ident("tag") {
tag = Tag::from_meta(item);
+ } else if path.is_ident("identifier") {
+ if let syn::Meta::NameValue(nv) = item {
+ identifier = match &nv.lit {
+ syn::Lit::Str(s) => Some(s.clone()),
+ _ => None,
+ };
+ }
} else if path.is_ident("size") {
size = Some(Value::from_meta(item));
} else if path.is_ident("value") {
@@ -507,6 +526,7 @@ impl<'config> VariantConfig<'config> {
extension_addition,
generics,
tag,
+ identifier,
variant,
constraints: Constraints {
extensible,
@@ -709,6 +729,7 @@ pub struct FieldConfig<'a> {
pub field: &'a syn::Field,
pub container_config: &'a Config,
pub tag: Option,
+ pub identifier: Option,
pub default: Option