From a471e9969e88fdf9e214e2752207e7a92c5d1849 Mon Sep 17 00:00:00 2001 From: JP Marcotte Date: Tue, 17 Mar 2026 20:51:43 -0400 Subject: [PATCH 1/2] feat: emit #[rasn(named_values(...))] for INTEGER types with NamedNumberList Wire `Integer.distinguished_values` into the rasn backend generator so that INTEGER types with a NamedNumberList produce a `named_values(...)` attribute annotation instead of silently dropping the named constants. - `utils.rs`: add `format_named_values_annotation()` using `Literal::i128_unsuffixed` for the values, consistent with how enum indices are formatted in `format_enum_members()` - `builder.rs`: push the annotation in `generate_integer()` after the range annotation, guarded by `Option::is_some()` - `rasn-compiler-tests/Cargo.toml`: point `rasn` to the local `fix/avn-named-integer` branch (path dep) so the compile-time `e2e_pdu!` check can validate the new attribute; was `version = "0.27"` which predates `named_values` support - Update 5 existing snapshots and add 1 new snapshot for the unbounded INTEGER with NamedNumberList (`integer_named_values_unbounded`) --- Cargo.lock | 50 +++++++++++++++++-- rasn-compiler-tests/Cargo.toml | 2 +- rasn-compiler-tests/tests/simple_types.rs | 22 ++++++++ ...edge_cases__distinguished_value_range.snap | 2 +- ...__distinguished_value_range_in_choice.snap | 2 +- ...ished_value_range_in_choice_from_impl.snap | 2 +- ...ases__enum_and_distinguished_defaults.snap | 2 +- ...e_types__integer_distinguished_values.snap | 2 +- ...types__integer_named_values_unbounded.snap | 21 ++++++++ rasn-compiler/src/generator/rasn/builder.rs | 3 ++ rasn-compiler/src/generator/rasn/utils.rs | 20 +++++++- 11 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 rasn-compiler-tests/tests/snapshots/simple_types__integer_named_values_unbounded.snap diff --git a/Cargo.lock b/Cargo.lock index 9cfdaa44..8a8a5a94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -543,7 +543,28 @@ dependencies = [ "num-integer", "num-traits", "once_cell", - "rasn-derive", + "rasn-derive 0.27.0", + "serde_json", + "snafu", + "xml-no-std", +] + +[[package]] +name = "rasn" +version = "0.28.10" +dependencies = [ + "bitvec", + "bitvec-nom2", + "bytes", + "cfg-if", + "chrono", + "either", + "nom 7.1.3", + "num-bigint", + "num-integer", + "num-traits", + "once_cell", + "rasn-derive 0.28.10", "serde_json", "snafu", "xml-no-std", @@ -583,7 +604,7 @@ dependencies = [ "bytes", "insta", "num-bigint", - "rasn", + "rasn 0.28.10", "rasn-compiler", "rasn-compiler-derive", "rasn-kerberos", @@ -596,7 +617,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf9723b0a85560548db5711650d32a2f10791addc7e998d3a59bdb2a12088d65" dependencies = [ "proc-macro2", - "rasn-derive-impl", + "rasn-derive-impl 0.27.0", + "syn", +] + +[[package]] +name = "rasn-derive" +version = "0.28.10" +dependencies = [ + "proc-macro2", + "rasn-derive-impl 0.28.10", "syn", ] @@ -614,13 +644,25 @@ dependencies = [ "uuid", ] +[[package]] +name = "rasn-derive-impl" +version = "0.28.10" +dependencies = [ + "either", + "itertools", + "proc-macro2", + "quote", + "syn", + "uuid", +] + [[package]] name = "rasn-kerberos" version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f469aa195413c1dedf1536cbd4dab2583e42a9938a2b146dbc45e53c920ef473" dependencies = [ - "rasn", + "rasn 0.27.0", ] [[package]] diff --git a/rasn-compiler-tests/Cargo.toml b/rasn-compiler-tests/Cargo.toml index 1b5c7d33..ef3f433a 100644 --- a/rasn-compiler-tests/Cargo.toml +++ b/rasn-compiler-tests/Cargo.toml @@ -15,7 +15,7 @@ readme.workspace = true [dependencies] rasn-compiler-derive = { path = "../rasn-compiler-derive" } rasn-compiler = { path = "../rasn-compiler" } -rasn = { version = "0.27" } +rasn = { path = "../../rasn", version = "0.28" } [dev-dependencies] bitvec = { version = "1" } diff --git a/rasn-compiler-tests/tests/simple_types.rs b/rasn-compiler-tests/tests/simple_types.rs index f1573b54..ca1adaff 100644 --- a/rasn-compiler-tests/tests/simple_types.rs +++ b/rasn-compiler-tests/tests/simple_types.rs @@ -27,6 +27,28 @@ e2e_pdu!( } (0..2)" ); +e2e_pdu!( + integer_named_values_unbounded, + "PUKKeyReferenceValue ::= INTEGER { + pukAppl1(1), + pukAppl2(2), + pukAppl3(3), + pukAppl4(4), + pukAppl5(5), + pukAppl6(6), + pukAppl7(7), + pukAppl8(8), + secondPUKAppl1(129), + secondPUKAppl2(130), + secondPUKAppl3(131), + secondPUKAppl4(132), + secondPUKAppl5(133), + secondPUKAppl6(134), + secondPUKAppl7(135), + secondPUKAppl8(136) + }" +); + e2e_pdu!( integer_const, r#" Test-Int ::= INTEGER diff --git a/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range.snap b/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range.snap index 2d98fa67..de665a3d 100644 --- a/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range.snap +++ b/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range.snap @@ -16,7 +16,7 @@ pub mod test_module { use rasn::prelude::*; use std::sync::LazyLock; #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] - #[rasn(delegate, value("1..=10"))] + # [rasn (delegate , value ("1..=10") , named_values ("first" = 1 , "second" = 2 , "third" = 3 , "fourth" = 4 , "fifth" = 5 , "sixth" = 6 , "seventh" = 7 , "eighth" = 8 , "ninth" = 9 , "tenth" = 10))] pub struct Distinguished(pub u8); #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] #[rasn(delegate, value("2..=8"))] diff --git a/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice.snap b/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice.snap index f892b60c..2334c907 100644 --- a/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice.snap +++ b/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice.snap @@ -16,7 +16,7 @@ pub mod test_module { use rasn::prelude::*; use std::sync::LazyLock; #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] - #[rasn(delegate, value("1..=10"))] + # [rasn (delegate , value ("1..=10") , named_values ("first" = 1 , "second" = 2 , "third" = 3 , "fourth" = 4 , "fifth" = 5 , "sixth" = 6 , "seventh" = 7 , "eighth" = 8 , "ninth" = 9 , "tenth" = 10))] pub struct Distinguished(pub u8); #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] #[rasn(choice, automatic_tags)] diff --git a/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice_from_impl.snap b/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice_from_impl.snap index b072f8f9..b380254b 100644 --- a/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice_from_impl.snap +++ b/rasn-compiler-tests/tests/snapshots/edge_cases__distinguished_value_range_in_choice_from_impl.snap @@ -16,7 +16,7 @@ pub mod test_module { use rasn::prelude::*; use std::sync::LazyLock; #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] - #[rasn(delegate, value("1..=10"))] + # [rasn (delegate , value ("1..=10") , named_values ("first" = 1 , "second" = 2 , "third" = 3 , "fourth" = 4 , "fifth" = 5 , "sixth" = 6 , "seventh" = 7 , "eighth" = 8 , "ninth" = 9 , "tenth" = 10))] pub struct Distinguished(pub u8); #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] #[rasn(choice, automatic_tags)] diff --git a/rasn-compiler-tests/tests/snapshots/edge_cases__enum_and_distinguished_defaults.snap b/rasn-compiler-tests/tests/snapshots/edge_cases__enum_and_distinguished_defaults.snap index f69316b5..2a78b6a2 100644 --- a/rasn-compiler-tests/tests/snapshots/edge_cases__enum_and_distinguished_defaults.snap +++ b/rasn-compiler-tests/tests/snapshots/edge_cases__enum_and_distinguished_defaults.snap @@ -22,7 +22,7 @@ pub mod test_module { second = 2, } #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] - #[rasn(delegate, value("1..=10"))] + # [rasn (delegate , value ("1..=10") , named_values ("first" = 1 , "second" = 2))] pub struct IntWithDefault(pub u8); #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] #[rasn(automatic_tags)] diff --git a/rasn-compiler-tests/tests/snapshots/simple_types__integer_distinguished_values.snap b/rasn-compiler-tests/tests/snapshots/simple_types__integer_distinguished_values.snap index 45db487e..42ad7ce6 100644 --- a/rasn-compiler-tests/tests/snapshots/simple_types__integer_distinguished_values.snap +++ b/rasn-compiler-tests/tests/snapshots/simple_types__integer_distinguished_values.snap @@ -16,6 +16,6 @@ pub mod test_module { use rasn::prelude::*; use std::sync::LazyLock; #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] - #[rasn(delegate, identifier = "Test-Int", value("0..=2"))] + # [rasn (delegate , identifier = "Test-Int" , value ("0..=2") , named_values ("first" = 0 , "second" = 1 , "third" = 2))] pub struct TestInt(pub u8); } diff --git a/rasn-compiler-tests/tests/snapshots/simple_types__integer_named_values_unbounded.snap b/rasn-compiler-tests/tests/snapshots/simple_types__integer_named_values_unbounded.snap new file mode 100644 index 00000000..e4cfc73e --- /dev/null +++ b/rasn-compiler-tests/tests/snapshots/simple_types__integer_named_values_unbounded.snap @@ -0,0 +1,21 @@ +--- +source: rasn-compiler-tests/tests/simple_types.rs +description: "PUKKeyReferenceValue ::= INTEGER {\n pukAppl1(1),\n pukAppl2(2),\n pukAppl3(3),\n pukAppl4(4),\n pukAppl5(5),\n pukAppl6(6),\n pukAppl7(7),\n pukAppl8(8),\n secondPUKAppl1(129),\n secondPUKAppl2(130),\n secondPUKAppl3(131),\n secondPUKAppl4(132),\n secondPUKAppl5(133),\n secondPUKAppl6(134),\n secondPUKAppl7(135),\n secondPUKAppl8(136)\n }" +--- +Generated: +#[allow( + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused, + clippy::too_many_arguments +)] +pub mod test_module { + extern crate alloc; + use core::borrow::Borrow; + use rasn::prelude::*; + use std::sync::LazyLock; + #[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, Eq, Hash)] + # [rasn (delegate , named_values ("pukAppl1" = 1 , "pukAppl2" = 2 , "pukAppl3" = 3 , "pukAppl4" = 4 , "pukAppl5" = 5 , "pukAppl6" = 6 , "pukAppl7" = 7 , "pukAppl8" = 8 , "secondPUKAppl1" = 129 , "secondPUKAppl2" = 130 , "secondPUKAppl3" = 131 , "secondPUKAppl4" = 132 , "secondPUKAppl5" = 133 , "secondPUKAppl6" = 134 , "secondPUKAppl7" = 135 , "secondPUKAppl8" = 136))] + pub struct PUKKeyReferenceValue(pub Integer); +} diff --git a/rasn-compiler/src/generator/rasn/builder.rs b/rasn-compiler/src/generator/rasn/builder.rs index 3272a1b4..9638602b 100644 --- a/rasn-compiler/src/generator/rasn/builder.rs +++ b/rasn-compiler/src/generator/rasn/builder.rs @@ -162,6 +162,9 @@ impl Rasn { if let ASN1Type::Integer(ref int) = tld.ty { let (name, mut annotations) = self.format_name_and_common_annotations(&tld); annotations.push(self.format_range_annotations(true, &int.constraints)?); + if let Some(ref dvs) = int.distinguished_values { + annotations.push(self.format_named_values_annotation(dvs)); + } Ok(integer_template( self.format_comments(&tld.comments), name, diff --git a/rasn-compiler/src/generator/rasn/utils.rs b/rasn-compiler/src/generator/rasn/utils.rs index 7d52e7bd..da61ca0f 100644 --- a/rasn-compiler/src/generator/rasn/utils.rs +++ b/rasn-compiler/src/generator/rasn/utils.rs @@ -13,7 +13,7 @@ use crate::{ per_visible_range_constraints, CharsetSubset, PerVisibleAlphabetConstraints, }, information_object::{InformationObjectField, ObjectClassDefn}, - types::{Choice, ChoiceOption, Enumerated, SequenceOrSet, SequenceOrSetMember}, + types::{Choice, ChoiceOption, DistinguishedValue, Enumerated, SequenceOrSet, SequenceOrSetMember}, ASN1Type, ASN1Value, AsnTag, CharacterStringType, IntegerType, TagClass, TaggingEnvironment, ToplevelDefinition, ToplevelTypeDefinition, }, @@ -221,6 +221,24 @@ impl Rasn { ) } + /// Formats a `named_values(...)` rasn annotation for INTEGER types with a NamedNumberList. + /// Returns an empty `TokenStream` when the slice is empty so callers can push it + /// unconditionally and `join_annotations` will filter it out. + pub(crate) fn format_named_values_annotation( + &self, + distinguished_values: &[DistinguishedValue], + ) -> TokenStream { + if distinguished_values.is_empty() { + return TokenStream::new(); + } + let pairs = distinguished_values.iter().map(|dv| { + let name = &dv.name; + let value = Literal::i128_unsuffixed(dv.value); + quote!(#name = #value) + }); + quote!(named_values(#(#pairs),*)) + } + pub(crate) fn format_alphabet_annotations( &self, string_type: CharacterStringType, From 41070ae284c25a500619c0b784262bac9998ebdd Mon Sep 17 00:00:00 2001 From: JP Marcotte Date: Tue, 17 Mar 2026 20:59:05 -0400 Subject: [PATCH 2/2] chore: use git dep for rasn fork branch instead of local path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Point rasn-compiler-tests at jp-marcotte/rasn#fix/avn-named-integer (git dependency) so CI can resolve the named_values derive macro support required by ITU-T X.680 ยง19 NamedNumberList emission. --- Cargo.lock | 3 +++ rasn-compiler-tests/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8a8a5a94..16a3f85a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -552,6 +552,7 @@ dependencies = [ [[package]] name = "rasn" version = "0.28.10" +source = "git+https://github.com/jp-marcotte/rasn.git?branch=fix%2Favn-named-integer#8b25f400089b855e56ac27413082e3f9806b0749" dependencies = [ "bitvec", "bitvec-nom2", @@ -624,6 +625,7 @@ dependencies = [ [[package]] name = "rasn-derive" version = "0.28.10" +source = "git+https://github.com/jp-marcotte/rasn.git?branch=fix%2Favn-named-integer#8b25f400089b855e56ac27413082e3f9806b0749" dependencies = [ "proc-macro2", "rasn-derive-impl 0.28.10", @@ -647,6 +649,7 @@ dependencies = [ [[package]] name = "rasn-derive-impl" version = "0.28.10" +source = "git+https://github.com/jp-marcotte/rasn.git?branch=fix%2Favn-named-integer#8b25f400089b855e56ac27413082e3f9806b0749" dependencies = [ "either", "itertools", diff --git a/rasn-compiler-tests/Cargo.toml b/rasn-compiler-tests/Cargo.toml index ef3f433a..55a18c57 100644 --- a/rasn-compiler-tests/Cargo.toml +++ b/rasn-compiler-tests/Cargo.toml @@ -15,7 +15,7 @@ readme.workspace = true [dependencies] rasn-compiler-derive = { path = "../rasn-compiler-derive" } rasn-compiler = { path = "../rasn-compiler" } -rasn = { path = "../../rasn", version = "0.28" } +rasn = { git = "https://github.com/jp-marcotte/rasn.git", branch = "fix/avn-named-integer" } [dev-dependencies] bitvec = { version = "1" }