1pub mod constraints;
10pub mod encoding_rules;
11pub mod error;
12pub mod information_object;
13pub mod parameterization;
14pub mod types;
15pub mod utils;
16
17use std::{borrow::Cow, cell::RefCell, collections::BTreeMap, ops::Add, rc::Rc};
18
19use crate::common::INTERNAL_IO_FIELD_REF_TYPE_NAME_PREFIX;
20use constraints::Constraint;
21use error::{GrammarError, GrammarErrorType};
22use information_object::{InformationObjectFieldReference, ToplevelInformationDefinition};
23#[cfg(test)]
24use internal_macros::EnumDebug;
25use parameterization::Parameterization;
26use quote::{quote, ToTokens, TokenStreamExt};
27use types::*;
28
29pub const BLOCK_COMMENT_START: &str = "/*";
31pub const BLOCK_COMMENT_END: &str = "*/";
32pub const LINE_COMMENT: &str = "--";
33
34pub const LEFT_PARENTHESIS: char = '(';
36pub const RIGHT_PARENTHESIS: char = ')';
37pub const LEFT_BRACKET: char = '[';
38pub const RIGHT_BRACKET: char = ']';
39pub const LEFT_BRACE: char = '{';
40pub const RIGHT_BRACE: char = '}';
41pub const LEFT_CHEVRON: char = '<';
42pub const RIGHT_CHEVRON: char = '>';
43
44pub const NULL: &str = "NULL";
46pub const BOOLEAN: &str = "BOOLEAN";
47pub const INTEGER: &str = "INTEGER";
48pub const REAL: &str = "REAL";
49pub const BIT_STRING: &str = "BIT STRING";
50pub const OCTET_STRING: &str = "OCTET STRING";
51pub const IA5_STRING: &str = "IA5String";
52pub const UTF8_STRING: &str = "UTF8String";
53pub const NUMERIC_STRING: &str = "NumericString";
54pub const VISIBLE_STRING: &str = "VisibleString";
55pub const TELETEX_STRING: &str = "TeletexString";
56pub const VIDEOTEX_STRING: &str = "VideotexString";
57pub const GRAPHIC_STRING: &str = "GraphicString";
58pub const GENERAL_STRING: &str = "GeneralString";
59pub const UNIVERSAL_STRING: &str = "UniversalString";
60pub const BMP_STRING: &str = "BMPString";
61pub const PRINTABLE_STRING: &str = "PrintableString";
62pub const GENERALIZED_TIME: &str = "GeneralizedTime";
63pub const UTC_TIME: &str = "UTCTime";
64pub const ENUMERATED: &str = "ENUMERATED";
65pub const CHOICE: &str = "CHOICE";
66pub const SEQUENCE: &str = "SEQUENCE";
67pub const SEQUENCE_OF: &str = "SEQUENCE OF";
68pub const SET_OF: &str = "SET OF";
69pub const OF: &str = "OF";
70pub const ALL: &str = "ALL";
71pub const SET: &str = "SET";
72pub const OBJECT_IDENTIFIER: &str = "OBJECT IDENTIFIER";
73pub const COMPONENTS_OF: &str = "COMPONENTS OF";
74
75pub const UNIVERSAL: &str = "UNIVERSAL";
77pub const PRIVATE: &str = "PRIVATE";
78pub const APPLICATION: &str = "APPLICATION";
79
80pub const TRUE: &str = "TRUE";
82pub const FALSE: &str = "FALSE";
83
84pub const BEGIN: &str = "BEGIN";
86pub const END: &str = "END";
87pub const DEFINITIONS: &str = "DEFINITIONS";
88pub const AUTOMATIC: &str = "AUTOMATIC";
89pub const EXPLICIT: &str = "EXPLICIT";
90pub const IMPLICIT: &str = "IMPLICIT";
91pub const IMPORTS: &str = "IMPORTS";
92pub const EXPORTS: &str = "EXPORTS";
93pub const FROM: &str = "FROM";
94pub const INSTRUCTIONS: &str = "INSTRUCTIONS";
95pub const TAGS: &str = "TAGS";
96pub const EXTENSIBILITY_IMPLIED: &str = "EXTENSIBILITY IMPLIED";
97pub const WITH_SUCCESSORS: &str = "WITH SUCCESSORS";
98pub const WITH_DESCENDANTS: &str = "WITH DESCENDANTS";
99pub const SEMICOLON: char = ';';
100
101pub const AMPERSAND: char = '&';
103pub const CLASS: &str = "CLASS";
104pub const UNIQUE: &str = "UNIQUE";
105pub const WITH_SYNTAX: &str = "WITH SYNTAX";
106pub const AT: char = '@';
107pub const DOT: char = '.';
108
109pub const SIZE: &str = "SIZE";
111pub const CONSTRAINED_BY: &str = "CONSTRAINED BY";
112pub const PATTERN: &str = "PATTERN";
113pub const DEFAULT: &str = "DEFAULT";
114pub const CONTAINING: &str = "CONTAINING";
115pub const ENCODED_BY: &str = "ENCODED BY";
116pub const OPTIONAL: &str = "OPTIONAL";
117pub const WITH_COMPONENTS: &str = "WITH COMPONENTS";
118pub const WITH_COMPONENT: &str = "WITH COMPONENT";
119pub const UNION: &str = "UNION";
120pub const EXCEPT: &str = "EXCEPT";
121pub const INTERSECTION: &str = "INTERSECTION";
122pub const ABSENT: &str = "ABSENT";
123pub const PRESENT: &str = "PRESENT";
124pub const INCLUDES: &str = "INCLUDES";
125pub const MIN: &str = "MIN";
126pub const MAX: &str = "MAX";
127pub const LESS_THAN: char = '<';
128pub const GREATER_THAN: char = '>';
129pub const PIPE: &str = "|";
130pub const CARET: &str = "^";
131
132pub const ASSIGN: &str = "::=";
133pub const RANGE: &str = "..";
134pub const ELLIPSIS: &str = "...";
135pub const COMMA: char = ',';
136pub const COLON: char = ':';
137pub const SINGLE_QUOTE: char = '\'';
138
139pub const ABSTRACT_SYNTAX: &str = "ABSTRACT-SYNTAX";
141pub const BIT: &str = "BIT";
142pub const CHARACTER: &str = "CHARACTER";
143pub const DATE: &str = "DATE";
144pub const DATE_TIME: &str = "DATE-TIME";
145pub const DURATION: &str = "DURATION";
146pub const EMBEDDED_PDV: &str = "EMBEDDED PDV";
147pub const EXTERNAL: &str = "EXTERNAL";
148pub const INSTANCE_OF: &str = "INSTANCE OF";
149pub const MINUS_INFINITY: &str = "MINUS-INFINITY";
150pub const NOT_A_NUMBER: &str = "NOT-A-NUMBER";
151pub const OBJECT: &str = "OBJECT";
152pub const OCTET: &str = "OCTET";
153pub const OID_IRI: &str = "OID-IRI";
154pub const PLUS_INFINITY: &str = "PLUS-INFINITY";
155pub const RELATIVE_OID: &str = "RELATIVE-OID";
156pub const RELATIVE_OID_IRI: &str = "RELATIVE-OID-IRI";
157pub const TIME: &str = "TIME";
158pub const TIME_OF_DAY: &str = "TIME-OF-DAY";
159pub const TYPE_IDENTIFIER: &str = "TYPE-IDENTIFIER";
160pub const ENCODING_CONTROL: &str = "ENCODING-CONTROL";
161
162pub const ASN1_KEYWORDS: [&str; 63] = [
163 ABSTRACT_SYNTAX,
164 BIT,
165 CHARACTER,
166 CONTAINING,
167 DATE,
168 DATE_TIME,
169 DURATION,
170 EMBEDDED_PDV,
171 EXTERNAL,
172 INSTANCE_OF,
173 MINUS_INFINITY,
174 NOT_A_NUMBER,
175 OBJECT,
176 OCTET,
177 OID_IRI,
178 PLUS_INFINITY,
179 RELATIVE_OID,
180 RELATIVE_OID_IRI,
181 TIME,
182 TIME_OF_DAY,
183 TYPE_IDENTIFIER,
184 SIZE,
185 DEFAULT,
186 OPTIONAL,
187 WITH_COMPONENTS,
188 WITH_COMPONENT,
189 UNION,
190 EXCEPT,
191 INTERSECTION,
192 ABSENT,
193 PRESENT,
194 INCLUDES,
195 MIN,
196 MAX,
197 CLASS,
198 UNIQUE,
199 WITH_SYNTAX,
200 NULL,
201 BOOLEAN,
202 INTEGER,
203 REAL,
204 ENUMERATED,
205 CHOICE,
206 SEQUENCE,
207 OF,
208 ALL,
209 SET,
210 OBJECT_IDENTIFIER,
211 UNIVERSAL,
212 PRIVATE,
213 APPLICATION,
214 TRUE,
215 FALSE,
216 BEGIN,
217 END,
218 DEFINITIONS,
219 AUTOMATIC,
220 EXPLICIT,
221 IMPLICIT,
222 IMPORTS,
223 FROM,
224 INSTRUCTIONS,
225 TAGS,
226];
227
228macro_rules! grammar_error {
229 ($kind:ident, $($arg:tt)*) => {
230 GrammarError::new(&format!($($arg)*),GrammarErrorType::$kind)
231 };
232}
233
234#[derive(Debug, Clone, PartialEq)]
235pub struct EncodingReferenceDefault(pub String);
236
237impl From<&str> for EncodingReferenceDefault {
238 fn from(value: &str) -> Self {
239 Self(value.into())
240 }
241}
242
243#[cfg_attr(test, derive(EnumDebug))]
244#[cfg_attr(not(test), derive(Debug))]
245#[derive(Clone, Copy, PartialEq, Default)]
246pub enum TaggingEnvironment {
247 Automatic,
248 #[default]
249 Implicit,
250 Explicit,
251}
252
253impl Add<&TaggingEnvironment> for &TaggingEnvironment {
254 type Output = TaggingEnvironment;
255
256 fn add(self, rhs: &TaggingEnvironment) -> Self::Output {
257 match (self, rhs) {
258 (t, TaggingEnvironment::Automatic) => *t,
259 (_, t) => *t,
260 }
261 }
262}
263
264#[cfg_attr(test, derive(EnumDebug))]
267#[cfg_attr(not(test), derive(Debug))]
268#[derive(Clone, Copy, PartialEq, Default)]
269pub enum ExtensibilityEnvironment {
270 Implied,
271 #[default]
272 Explicit,
273}
274
275#[cfg_attr(test, derive(EnumDebug))]
278#[cfg_attr(not(test), derive(Debug))]
279#[derive(Clone, PartialEq)]
280pub enum With {
281 Successors,
282 Descendants,
283}
284
285#[derive(Debug, Clone, PartialEq)]
288pub struct ExternalValueReference {
289 pub module_reference: String,
290 pub value_reference: String,
291}
292
293#[derive(Debug, Clone, PartialEq)]
296pub struct GlobalModuleReference {
297 pub module_reference: String,
298 pub assigned_identifier: AssignedIdentifier,
299}
300
301impl From<(&str, AssignedIdentifier)> for GlobalModuleReference {
302 fn from(value: (&str, AssignedIdentifier)) -> Self {
303 Self {
304 module_reference: value.0.to_owned(),
305 assigned_identifier: value.1,
306 }
307 }
308}
309
310#[cfg_attr(test, derive(EnumDebug))]
313#[cfg_attr(not(test), derive(Debug))]
314#[derive(Clone, PartialEq)]
315pub enum AssignedIdentifier {
316 ObjectIdentifierValue(ObjectIdentifierValue),
317 ExternalValueReference(ExternalValueReference),
318 ValueReference(String),
319 ParameterizedValue {
320 value_reference: String,
321 actual_parameter_list: String,
322 },
323 Empty,
324}
325
326#[derive(Debug, Clone, PartialEq)]
329pub struct Import {
330 pub types: Vec<String>,
331 pub global_module_reference: GlobalModuleReference,
332 pub with: Option<With>,
333}
334
335impl From<(Vec<&str>, (GlobalModuleReference, Option<&str>))> for Import {
336 fn from(value: (Vec<&str>, (GlobalModuleReference, Option<&str>))) -> Self {
337 Self {
338 types: value.0.into_iter().map(String::from).collect(),
339 global_module_reference: value.1 .0,
340 with: value.1 .1.map(|with| {
341 if with == WITH_SUCCESSORS {
342 With::Successors
343 } else {
344 With::Descendants
345 }
346 }),
347 }
348 }
349}
350
351#[cfg_attr(test, derive(EnumDebug))]
354#[cfg_attr(not(test), derive(Debug))]
355#[derive(Clone, PartialEq)]
356pub enum Exports {
357 Identifier(Vec<String>),
358 All,
359}
360
361impl From<Vec<&str>> for Exports {
362 fn from(value: Vec<&str>) -> Self {
363 Self::Identifier(value.iter().map(ToString::to_string).collect())
364 }
365}
366
367#[cfg_attr(test, derive(EnumDebug))]
370#[cfg_attr(not(test), derive(Debug))]
371#[derive(Clone, PartialEq)]
372pub enum DefinitiveIdentifier {
373 DefinitiveOID(ObjectIdentifierValue),
374 DefinitiveOIDandIRI {
375 oid: ObjectIdentifierValue,
376 iri: String,
377 },
378}
379
380impl From<(ObjectIdentifierValue, Option<&str>)> for DefinitiveIdentifier {
381 fn from(value: (ObjectIdentifierValue, Option<&str>)) -> Self {
382 if let Some(iri_value) = value.1 {
383 Self::DefinitiveOIDandIRI {
384 oid: value.0,
385 iri: iri_value.to_owned(),
386 }
387 } else {
388 Self::DefinitiveOID(value.0)
389 }
390 }
391}
392
393#[derive(Debug, Clone, PartialEq)]
396pub struct ModuleReference {
397 pub name: String,
398 pub module_identifier: Option<DefinitiveIdentifier>,
399 pub encoding_reference_default: Option<EncodingReferenceDefault>,
400 pub tagging_environment: TaggingEnvironment,
401 pub extensibility_environment: ExtensibilityEnvironment,
402 pub imports: Vec<Import>,
403 pub exports: Option<Exports>,
404}
405
406impl ModuleReference {
407 pub fn find_import(&self, identifier: &str) -> Option<&String> {
409 self.imports
410 .iter()
411 .find_map(|i| i.types.iter().find(|id| *id == identifier))
412 }
413}
414
415impl
416 From<(
417 &str,
418 Option<DefinitiveIdentifier>,
419 Option<(
420 Option<EncodingReferenceDefault>,
421 TaggingEnvironment,
422 ExtensibilityEnvironment,
423 )>,
424 Option<Exports>,
425 Option<Vec<Import>>,
426 )> for ModuleReference
427{
428 fn from(
429 value: (
430 &str,
431 Option<DefinitiveIdentifier>,
432 Option<(
433 Option<EncodingReferenceDefault>,
434 TaggingEnvironment,
435 ExtensibilityEnvironment,
436 )>,
437 Option<Exports>,
438 Option<Vec<Import>>,
439 ),
440 ) -> Self {
441 let (encoding_reference_default, tagging_environment, extensibility_environment) =
442 value.2.unwrap_or((
443 None,
444 TaggingEnvironment::Explicit,
445 ExtensibilityEnvironment::Explicit,
446 ));
447 Self {
448 name: value.0.into(),
449 module_identifier: value.1,
450 encoding_reference_default,
451 tagging_environment,
452 extensibility_environment,
453 exports: value.3,
454 imports: value.4.unwrap_or_default(),
455 }
456 }
457}
458
459#[derive(Debug, Clone, PartialEq)]
462pub struct ObjectIdentifierValue(pub Vec<ObjectIdentifierArc>);
463
464impl From<Vec<ObjectIdentifierArc>> for ObjectIdentifierValue {
465 fn from(value: Vec<ObjectIdentifierArc>) -> Self {
466 Self(value)
467 }
468}
469
470#[derive(Debug, Clone, PartialEq)]
473pub struct ObjectIdentifierArc {
474 pub name: Option<String>,
475 pub number: Option<u128>,
476}
477
478impl From<u128> for ObjectIdentifierArc {
479 fn from(value: u128) -> Self {
480 Self {
481 name: None,
482 number: Some(value),
483 }
484 }
485}
486
487impl From<&str> for ObjectIdentifierArc {
488 fn from(value: &str) -> Self {
489 Self {
490 name: Some(value.into()),
491 number: None,
492 }
493 }
494}
495
496impl From<(&str, u128)> for ObjectIdentifierArc {
497 fn from(value: (&str, u128)) -> Self {
498 Self {
499 name: Some(value.0.into()),
500 number: Some(value.1),
501 }
502 }
503}
504
505#[cfg_attr(test, derive(EnumDebug))]
514#[cfg_attr(not(test), derive(Debug))]
515#[derive(Clone, PartialEq)]
516pub enum ToplevelDefinition {
517 Type(ToplevelTypeDefinition),
518 Value(ToplevelValueDefinition),
519 Information(ToplevelInformationDefinition),
520}
521
522impl ToplevelDefinition {
523 pub(crate) fn has_enum_value(&self, type_name: Option<&String>, identifier: &String) -> bool {
524 if let ToplevelDefinition::Type(ToplevelTypeDefinition {
525 name,
526 ty: ASN1Type::Enumerated(e),
527 ..
528 }) = self
529 {
530 if type_name.is_some() && Some(name) != type_name {
531 return false;
532 }
533 e.members.iter().any(|m| &m.name == identifier)
534 } else {
535 false
536 }
537 }
538
539 pub(crate) fn set_index(
540 &mut self,
541 module_reference: Rc<RefCell<ModuleReference>>,
542 item_no: usize,
543 ) {
544 match self {
545 ToplevelDefinition::Type(ref mut t) => {
546 t.index = Some((module_reference, item_no));
547 }
548 ToplevelDefinition::Value(ref mut v) => {
549 v.index = Some((module_reference, item_no));
550 }
551 ToplevelDefinition::Information(ref mut i) => {
552 i.index = Some((module_reference, item_no));
553 }
554 }
555 }
556
557 pub(crate) fn get_index(&self) -> Option<&(Rc<RefCell<ModuleReference>>, usize)> {
558 match self {
559 ToplevelDefinition::Type(ref t) => t.index.as_ref(),
560 ToplevelDefinition::Value(ref v) => v.index.as_ref(),
561 ToplevelDefinition::Information(ref i) => i.index.as_ref(),
562 }
563 }
564
565 pub(crate) fn get_module_reference(&self) -> Option<Rc<RefCell<ModuleReference>>> {
566 match self {
567 ToplevelDefinition::Type(ref t) => t.index.as_ref().map(|(m, _)| m.clone()),
568 ToplevelDefinition::Value(ref v) => v.index.as_ref().map(|(m, _)| m.clone()),
569 ToplevelDefinition::Information(ref i) => i.index.as_ref().map(|(m, _)| m.clone()),
570 }
571 }
572
573 pub(crate) fn apply_tagging_environment(&mut self, environment: &TaggingEnvironment) {
574 if let (env, ToplevelDefinition::Type(ty)) = (environment, self) {
575 ty.tag = ty.tag.as_ref().map(|t| AsnTag {
576 environment: env + &t.environment,
577 tag_class: t.tag_class,
578 id: t.id,
579 });
580 match &mut ty.ty {
581 ASN1Type::Sequence(s) | ASN1Type::Set(s) => s.members.iter_mut().for_each(|m| {
582 m.tag = m.tag.as_ref().map(|t| AsnTag {
583 environment: env + &t.environment,
584 tag_class: t.tag_class,
585 id: t.id,
586 });
587 }),
588 ASN1Type::Choice(c) => c.options.iter_mut().for_each(|o| {
589 o.tag = o.tag.as_ref().map(|t| AsnTag {
590 environment: env + &t.environment,
591 tag_class: t.tag_class,
592 id: t.id,
593 });
594 }),
595 _ => (),
596 }
597 }
598 }
599
600 pub fn name(&self) -> &String {
622 match self {
623 ToplevelDefinition::Information(i) => &i.name,
624 ToplevelDefinition::Type(t) => &t.name,
625 ToplevelDefinition::Value(v) => &v.name,
626 }
627 }
628}
629
630#[derive(Debug, Clone, PartialEq)]
633pub struct ToplevelValueDefinition {
634 pub comments: String,
635 pub name: String,
636 pub associated_type: ASN1Type,
637 pub parameterization: Option<Parameterization>,
638 pub value: ASN1Value,
639 pub index: Option<(Rc<RefCell<ModuleReference>>, usize)>,
640}
641
642impl From<(&str, ASN1Value, ASN1Type)> for ToplevelValueDefinition {
643 fn from(value: (&str, ASN1Value, ASN1Type)) -> Self {
644 Self {
645 comments: String::new(),
646 name: value.0.to_owned(),
647 associated_type: value.2.to_owned(),
648 parameterization: None,
649 value: value.1,
650 index: None,
651 }
652 }
653}
654
655impl
656 From<(
657 Vec<&str>,
658 &str,
659 Option<Parameterization>,
660 ASN1Type,
661 ASN1Value,
662 )> for ToplevelValueDefinition
663{
664 fn from(
665 value: (
666 Vec<&str>,
667 &str,
668 Option<Parameterization>,
669 ASN1Type,
670 ASN1Value,
671 ),
672 ) -> Self {
673 Self {
674 comments: value.0.join("\n"),
675 name: value.1.into(),
676 parameterization: value.2,
677 associated_type: value.3,
678 value: value.4,
679 index: None,
680 }
681 }
682}
683
684#[derive(Debug, Clone, PartialEq)]
685pub struct ToplevelTypeDefinition {
686 pub comments: String,
687 pub tag: Option<AsnTag>,
688 pub name: String,
689 pub ty: ASN1Type,
690 pub parameterization: Option<Parameterization>,
691 pub index: Option<(Rc<RefCell<ModuleReference>>, usize)>,
692}
693
694impl ToplevelTypeDefinition {
695 pub fn pdu(&self) -> &ASN1Type {
696 &self.ty
697 }
698}
699
700impl From<(&str, ASN1Type)> for ToplevelTypeDefinition {
701 fn from(value: (&str, ASN1Type)) -> Self {
702 Self {
703 comments: String::new(),
704 tag: None,
705 name: value.0.to_owned(),
706 ty: value.1,
707 parameterization: None,
708 index: None,
709 }
710 }
711}
712
713impl
714 From<(
715 Vec<&str>,
716 &str,
717 Option<Parameterization>,
718 (Option<AsnTag>, ASN1Type),
719 )> for ToplevelTypeDefinition
720{
721 fn from(
722 value: (
723 Vec<&str>,
724 &str,
725 Option<Parameterization>,
726 (Option<AsnTag>, ASN1Type),
727 ),
728 ) -> Self {
729 Self {
730 comments: value.0.join("\n"),
731 name: value.1.into(),
732 parameterization: value.2,
733 ty: value.3 .1,
734 tag: value.3 .0,
735 index: None,
736 }
737 }
738}
739
740#[cfg_attr(test, derive(EnumDebug))]
744#[cfg_attr(not(test), derive(Debug))]
745#[derive(Clone, PartialEq)]
746pub enum ASN1Type {
747 Null,
748 Boolean(Boolean),
749 Integer(Integer),
750 Real(Real),
751 BitString(BitString),
752 OctetString(OctetString),
753 CharacterString(CharacterString),
754 Enumerated(Enumerated),
755 Choice(Choice),
756 Sequence(SequenceOrSet),
757 SequenceOf(SequenceOrSetOf),
758 Set(SequenceOrSet),
759 SetOf(SequenceOrSetOf),
760 Time(Time),
761 GeneralizedTime(GeneralizedTime),
762 UTCTime(UTCTime),
763 ElsewhereDeclaredType(DeclarationElsewhere),
764 ChoiceSelectionType(ChoiceSelectionType),
765 ObjectIdentifier(ObjectIdentifier),
766 InformationObjectFieldReference(InformationObjectFieldReference),
767 EmbeddedPdv,
768 External,
769}
770
771impl ASN1Type {
772 pub fn as_str(&self) -> Cow<'_, str> {
773 match self {
774 ASN1Type::Null => Cow::Borrowed(NULL),
775 ASN1Type::Boolean(_) => Cow::Borrowed(BOOLEAN),
776 ASN1Type::Integer(_) => Cow::Borrowed(INTEGER),
777 ASN1Type::Real(_) => Cow::Borrowed(REAL),
778 ASN1Type::BitString(_) => Cow::Borrowed(BIT_STRING),
779 ASN1Type::OctetString(_) => Cow::Borrowed(OCTET_STRING),
780 ASN1Type::CharacterString(CharacterString {
781 ty: CharacterStringType::BMPString,
782 ..
783 }) => Cow::Borrowed(BMP_STRING),
784 ASN1Type::CharacterString(CharacterString {
785 ty: CharacterStringType::UTF8String,
786 ..
787 }) => Cow::Borrowed(UTF8_STRING),
788 ASN1Type::CharacterString(CharacterString {
789 ty: CharacterStringType::PrintableString,
790 ..
791 }) => Cow::Borrowed(PRINTABLE_STRING),
792 ASN1Type::CharacterString(CharacterString {
793 ty: CharacterStringType::TeletexString,
794 ..
795 }) => Cow::Borrowed(TELETEX_STRING),
796 ASN1Type::CharacterString(CharacterString {
797 ty: CharacterStringType::IA5String,
798 ..
799 }) => Cow::Borrowed(IA5_STRING),
800 ASN1Type::CharacterString(CharacterString {
801 ty: CharacterStringType::UniversalString,
802 ..
803 }) => Cow::Borrowed(UNIVERSAL_STRING),
804 ASN1Type::CharacterString(CharacterString {
805 ty: CharacterStringType::VisibleString,
806 ..
807 }) => Cow::Borrowed(VISIBLE_STRING),
808 ASN1Type::CharacterString(CharacterString {
809 ty: CharacterStringType::GeneralString,
810 ..
811 }) => Cow::Borrowed(GENERAL_STRING),
812 ASN1Type::CharacterString(CharacterString {
813 ty: CharacterStringType::VideotexString,
814 ..
815 }) => Cow::Borrowed(VIDEOTEX_STRING),
816 ASN1Type::CharacterString(CharacterString {
817 ty: CharacterStringType::GraphicString,
818 ..
819 }) => Cow::Borrowed(GRAPHIC_STRING),
820 ASN1Type::CharacterString(CharacterString {
821 ty: CharacterStringType::NumericString,
822 ..
823 }) => Cow::Borrowed(NUMERIC_STRING),
824 ASN1Type::Enumerated(_) => Cow::Borrowed(ENUMERATED),
825 ASN1Type::Choice(_) => Cow::Borrowed(CHOICE),
826 ASN1Type::Sequence(_) => Cow::Borrowed(SEQUENCE),
827 ASN1Type::SequenceOf(_) => Cow::Borrowed(SEQUENCE_OF),
828 ASN1Type::Set(_) => Cow::Borrowed(SET),
829 ASN1Type::SetOf(_) => Cow::Borrowed(SET_OF),
830 ASN1Type::Time(_) => Cow::Borrowed(TIME),
831 ASN1Type::GeneralizedTime(_) => Cow::Borrowed(GENERALIZED_TIME),
832 ASN1Type::UTCTime(_) => Cow::Borrowed(UTC_TIME),
833 ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere { identifier, .. }) => {
834 Cow::Borrowed(identifier)
835 }
836 ASN1Type::ChoiceSelectionType(_) => todo!(),
837 ASN1Type::ObjectIdentifier(_) => Cow::Borrowed(OBJECT_IDENTIFIER),
838 ASN1Type::InformationObjectFieldReference(ifr) => Cow::Owned(format!(
839 "{INTERNAL_IO_FIELD_REF_TYPE_NAME_PREFIX}{}${}",
840 ifr.class,
841 ifr.field_path_as_str()
842 )),
843 ASN1Type::EmbeddedPdv => Cow::Borrowed(EMBEDDED_PDV),
844 ASN1Type::External => Cow::Borrowed(EXTERNAL),
845 }
846 }
847
848 pub fn builtin_or_elsewhere(
849 parent: Option<&str>,
850 identifier: &str,
851 constraints: Option<Vec<Constraint>>,
852 ) -> ASN1Type {
853 match (parent, identifier) {
854 (None, NULL) => ASN1Type::Null,
855 (None, BOOLEAN) => ASN1Type::Boolean(Boolean {
856 constraints: constraints.unwrap_or_default(),
857 }),
858 (None, REAL) => ASN1Type::Real(Real {
859 constraints: constraints.unwrap_or_default(),
860 }),
861 (None, INTEGER) => ASN1Type::Integer(Integer {
862 constraints: constraints.unwrap_or_default(),
863 distinguished_values: None,
864 }),
865 (None, BIT_STRING) => ASN1Type::BitString(BitString {
866 constraints: constraints.unwrap_or_default(),
867 distinguished_values: None,
868 }),
869 (None, OCTET_STRING) => ASN1Type::OctetString(OctetString {
870 constraints: constraints.unwrap_or_default(),
871 }),
872 (None, GENERALIZED_TIME) => ASN1Type::GeneralizedTime(GeneralizedTime {
873 constraints: constraints.unwrap_or_default(),
874 }),
875 (None, UTC_TIME) => ASN1Type::UTCTime(UTCTime {
876 constraints: constraints.unwrap_or_default(),
877 }),
878 (None, OBJECT_IDENTIFIER) => ASN1Type::ObjectIdentifier(ObjectIdentifier {
879 constraints: constraints.unwrap_or_default(),
880 }),
881 (None, BMP_STRING) => ASN1Type::CharacterString(CharacterString {
882 constraints: constraints.unwrap_or_default(),
883 ty: CharacterStringType::BMPString,
884 }),
885 (None, UTF8_STRING) => ASN1Type::CharacterString(CharacterString {
886 constraints: constraints.unwrap_or_default(),
887 ty: CharacterStringType::UTF8String,
888 }),
889 (None, PRINTABLE_STRING) => ASN1Type::CharacterString(CharacterString {
890 constraints: constraints.unwrap_or_default(),
891 ty: CharacterStringType::PrintableString,
892 }),
893 (None, TELETEX_STRING) => ASN1Type::CharacterString(CharacterString {
894 constraints: constraints.unwrap_or_default(),
895 ty: CharacterStringType::TeletexString,
896 }),
897 (None, IA5_STRING) => ASN1Type::CharacterString(CharacterString {
898 constraints: constraints.unwrap_or_default(),
899 ty: CharacterStringType::IA5String,
900 }),
901 (None, UNIVERSAL_STRING) => ASN1Type::CharacterString(CharacterString {
902 constraints: constraints.unwrap_or_default(),
903 ty: CharacterStringType::UniversalString,
904 }),
905 (None, VISIBLE_STRING) => ASN1Type::CharacterString(CharacterString {
906 constraints: constraints.unwrap_or_default(),
907 ty: CharacterStringType::VisibleString,
908 }),
909 (None, GENERAL_STRING) => ASN1Type::CharacterString(CharacterString {
910 constraints: constraints.unwrap_or_default(),
911 ty: CharacterStringType::GeneralString,
912 }),
913 (None, VIDEOTEX_STRING) => ASN1Type::CharacterString(CharacterString {
914 constraints: constraints.unwrap_or_default(),
915 ty: CharacterStringType::VideotexString,
916 }),
917 (None, GRAPHIC_STRING) => ASN1Type::CharacterString(CharacterString {
918 constraints: constraints.unwrap_or_default(),
919 ty: CharacterStringType::GraphicString,
920 }),
921 (None, NUMERIC_STRING) => ASN1Type::CharacterString(CharacterString {
922 constraints: constraints.unwrap_or_default(),
923 ty: CharacterStringType::NumericString,
924 }),
925 _ => ASN1Type::ElsewhereDeclaredType((parent, identifier, constraints).into()),
926 }
927 }
928
929 pub fn is_builtin_type(&self) -> bool {
930 !matches!(
931 self,
932 ASN1Type::ElsewhereDeclaredType(_)
933 | ASN1Type::ChoiceSelectionType(_)
934 | ASN1Type::InformationObjectFieldReference(_)
935 )
936 }
937
938 pub fn constraints(&self) -> Option<&Vec<Constraint>> {
939 match self {
940 ASN1Type::Boolean(b) => Some(b.constraints()),
941 ASN1Type::Real(r) => Some(r.constraints()),
942 ASN1Type::Integer(i) => Some(i.constraints()),
943 ASN1Type::BitString(b) => Some(b.constraints()),
944 ASN1Type::OctetString(o) => Some(o.constraints()),
945 ASN1Type::CharacterString(c) => Some(c.constraints()),
946 ASN1Type::Enumerated(e) => Some(e.constraints()),
947 ASN1Type::Time(t) => Some(t.constraints()),
948 ASN1Type::Choice(c) => Some(c.constraints()),
949 ASN1Type::Set(s) | ASN1Type::Sequence(s) => Some(s.constraints()),
950 ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => Some(s.constraints()),
951 ASN1Type::ElsewhereDeclaredType(e) => Some(e.constraints()),
952 ASN1Type::InformationObjectFieldReference(f) => Some(f.constraints()),
953 _ => None,
954 }
955 }
956
957 pub fn constraints_mut(&mut self) -> Option<&mut Vec<Constraint>> {
958 match self {
959 ASN1Type::Boolean(b) => Some(b.constraints_mut()),
960 ASN1Type::Real(r) => Some(r.constraints_mut()),
961 ASN1Type::Integer(i) => Some(i.constraints_mut()),
962 ASN1Type::BitString(b) => Some(b.constraints_mut()),
963 ASN1Type::OctetString(o) => Some(o.constraints_mut()),
964 ASN1Type::CharacterString(c) => Some(c.constraints_mut()),
965 ASN1Type::Enumerated(e) => Some(e.constraints_mut()),
966 ASN1Type::Time(t) => Some(t.constraints_mut()),
967 ASN1Type::Choice(c) => Some(c.constraints_mut()),
968 ASN1Type::Set(s) | ASN1Type::Sequence(s) => Some(s.constraints_mut()),
969 ASN1Type::SetOf(s) | ASN1Type::SequenceOf(s) => Some(s.constraints_mut()),
970 ASN1Type::ElsewhereDeclaredType(e) => Some(e.constraints_mut()),
971 ASN1Type::InformationObjectFieldReference(f) => Some(f.constraints_mut()),
972 _ => None,
973 }
974 }
975}
976
977pub const NUMERIC_STRING_CHARSET: [char; 11] =
978 [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
979pub const PRINTABLE_STRING_CHARSET: [char; 74] = [
980 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
981 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
982 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
983 '5', '6', '7', '8', '9', ' ', '\'', '(', ')', '+', ',', '-', '.', '/', ':', '=', '?',
984];
985
986#[cfg_attr(test, derive(EnumDebug))]
988#[cfg_attr(not(test), derive(Debug))]
989#[derive(Clone, PartialEq, Copy)]
990pub enum CharacterStringType {
991 NumericString,
992 VisibleString,
993 IA5String,
994 TeletexString,
995 VideotexString,
996 GraphicString,
997 GeneralString,
998 UniversalString,
999 UTF8String,
1000 BMPString,
1001 PrintableString,
1002}
1003
1004impl CharacterStringType {
1005 pub fn character_set(&self) -> BTreeMap<usize, char> {
1006 match self {
1007 CharacterStringType::NumericString => {
1008 NUMERIC_STRING_CHARSET.into_iter().enumerate().collect()
1009 }
1010 CharacterStringType::VisibleString | CharacterStringType::PrintableString => {
1011 PRINTABLE_STRING_CHARSET.into_iter().enumerate().collect()
1012 }
1013 CharacterStringType::IA5String => (0..128u32)
1014 .map(|i| char::from_u32(i).unwrap())
1015 .enumerate()
1016 .collect(),
1017 _ => (0..u16::MAX as u32)
1018 .filter_map(char::from_u32)
1019 .enumerate()
1020 .collect(),
1021 }
1022 }
1023}
1024
1025impl From<&str> for CharacterStringType {
1026 fn from(value: &str) -> Self {
1027 match value {
1028 IA5_STRING => Self::IA5String,
1029 NUMERIC_STRING => Self::NumericString,
1030 VISIBLE_STRING => Self::VisibleString,
1031 TELETEX_STRING => Self::TeletexString,
1032 VIDEOTEX_STRING => Self::VideotexString,
1033 GRAPHIC_STRING => Self::GraphicString,
1034 GENERAL_STRING => Self::GeneralString,
1035 UNIVERSAL_STRING => Self::UniversalString,
1036 BMP_STRING => Self::BMPString,
1037 PRINTABLE_STRING => Self::PrintableString,
1038 _ => Self::UTF8String,
1039 }
1040 }
1041}
1042
1043#[derive(Debug, Clone, Copy, PartialEq)]
1045pub enum IntegerType {
1046 Int8,
1047 Uint8,
1048 Int16,
1049 Uint16,
1050 Int32,
1051 Uint32,
1052 Int64,
1053 Uint64,
1054 Unbounded,
1055}
1056
1057impl ToTokens for IntegerType {
1058 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1059 match self {
1060 IntegerType::Int8 => tokens.append_all(quote!(i8)),
1061 IntegerType::Uint8 => tokens.append_all(quote!(u8)),
1062 IntegerType::Int16 => tokens.append_all(quote!(i16)),
1063 IntegerType::Uint16 => tokens.append_all(quote!(u16)),
1064 IntegerType::Int32 => tokens.append_all(quote!(i32)),
1065 IntegerType::Uint32 => tokens.append_all(quote!(u32)),
1066 IntegerType::Int64 => tokens.append_all(quote!(i64)),
1067 IntegerType::Uint64 => tokens.append_all(quote!(u64)),
1068 IntegerType::Unbounded => tokens.append_all(quote!(Integer)),
1069 }
1070 }
1071}
1072
1073impl IntegerType {
1074 pub fn is_unbounded(&self) -> bool {
1075 self == &IntegerType::Unbounded
1076 }
1077 pub fn max_restrictive(self, rhs: IntegerType) -> IntegerType {
1082 match (self, rhs) {
1083 (x, y) if x == y => x,
1084 (IntegerType::Uint8, _) | (_, IntegerType::Uint8) => IntegerType::Uint8,
1085 (IntegerType::Int8, _) | (_, IntegerType::Int8) => IntegerType::Int8,
1086 (IntegerType::Uint16, _) | (_, IntegerType::Uint16) => IntegerType::Uint16,
1087 (IntegerType::Int16, _) | (_, IntegerType::Int16) => IntegerType::Int16,
1088 (IntegerType::Uint32, _) | (_, IntegerType::Uint32) => IntegerType::Uint32,
1089 (IntegerType::Int32, _) | (_, IntegerType::Int32) => IntegerType::Int32,
1090 (IntegerType::Uint64, _) | (_, IntegerType::Uint64) => IntegerType::Uint64,
1091 (IntegerType::Int64, _) | (_, IntegerType::Int64) => IntegerType::Int64,
1092 _ => IntegerType::Unbounded,
1093 }
1094 }
1095}
1096
1097#[cfg_attr(test, derive(EnumDebug))]
1099#[cfg_attr(not(test), derive(Debug))]
1100#[derive(Clone, PartialEq)]
1101pub enum ASN1Value {
1102 All,
1103 Null,
1104 Boolean(bool),
1105 Choice {
1106 type_name: Option<String>,
1107 variant_name: String,
1108 inner_value: Box<ASN1Value>,
1109 },
1110 SequenceOrSet(Vec<(Option<String>, Box<ASN1Value>)>),
1113 Integer(i128),
1114 Real(f64),
1115 String(String),
1116 BitString(Vec<bool>),
1117 BitStringNamedBits(Vec<String>),
1118 OctetString(Vec<u8>),
1119 EnumeratedValue {
1120 enumerated: String,
1121 enumerable: String,
1122 },
1123 Time(String),
1124 ElsewhereDeclaredValue {
1125 parent: Option<String>,
1126 identifier: String,
1127 },
1128 ObjectIdentifier(ObjectIdentifierValue),
1129 LinkedNestedValue {
1142 supertypes: Vec<String>,
1144 value: Box<ASN1Value>,
1145 },
1146 LinkedIntValue {
1148 integer_type: IntegerType,
1149 value: i128,
1150 },
1151 LinkedStructLikeValue(Vec<(String, ASN1Type, StructLikeFieldValue)>),
1154 LinkedArrayLikeValue(Vec<Box<ASN1Value>>),
1156 LinkedCharStringValue(CharacterStringType, String),
1158 LinkedElsewhereDefinedValue {
1159 parent: Option<String>,
1160 identifier: String,
1161 can_be_const: bool,
1162 },
1163}
1164
1165#[cfg_attr(test, derive(EnumDebug))]
1167#[cfg_attr(not(test), derive(Debug))]
1168#[derive(Clone, PartialEq)]
1169pub enum StructLikeFieldValue {
1170 Explicit(Box<ASN1Value>),
1171 Implicit(Box<ASN1Value>),
1172}
1173
1174impl StructLikeFieldValue {
1175 pub fn into_value(self) -> ASN1Value {
1176 match self {
1177 StructLikeFieldValue::Explicit(v) | StructLikeFieldValue::Implicit(v) => *v,
1178 }
1179 }
1180
1181 pub fn value(&self) -> &ASN1Value {
1182 match self {
1183 StructLikeFieldValue::Explicit(v) | StructLikeFieldValue::Implicit(v) => v,
1184 }
1185 }
1186
1187 pub fn value_mut(&mut self) -> &mut ASN1Value {
1188 match self {
1189 StructLikeFieldValue::Explicit(ref mut v)
1190 | StructLikeFieldValue::Implicit(ref mut v) => &mut *v,
1191 }
1192 }
1193}
1194
1195impl AsMut<ASN1Value> for ASN1Value {
1196 fn as_mut(&mut self) -> &mut ASN1Value {
1197 self
1198 }
1199}
1200
1201impl ASN1Value {
1202 pub fn max(
1203 &self,
1204 other: &ASN1Value,
1205 char_set: Option<&BTreeMap<usize, char>>,
1206 ) -> Result<ASN1Value, GrammarError> {
1207 self.min_max(other, char_set, false)
1208 }
1209
1210 pub fn min(
1211 &self,
1212 other: &ASN1Value,
1213 char_set: Option<&BTreeMap<usize, char>>,
1214 ) -> Result<ASN1Value, GrammarError> {
1215 self.min_max(other, char_set, true)
1216 }
1217
1218 fn min_max(
1219 &self,
1220 other: &ASN1Value,
1221 char_set: Option<&BTreeMap<usize, char>>,
1222 getting_mininum: bool,
1223 ) -> Result<ASN1Value, GrammarError> {
1224 match (self, other, char_set) {
1225 (ASN1Value::Integer(s), ASN1Value::Integer(o), _) => {
1226 if getting_mininum {
1227 Ok(ASN1Value::Integer(*s.min(o)))
1228 } else {
1229 Ok(ASN1Value::Integer(*s.max(o)))
1230 }
1231 }
1232 (ASN1Value::String(s), ASN1Value::String(o), Some(set)) => {
1233 if s.len() != 1 || o.len() != 1 {
1234 return Err(grammar_error!(
1235 UnpackingError,
1236 "Unsupported operation for ASN1Values {self:?} and {other:?}"
1237 ));
1238 }
1239 let s_as_char = s.chars().next().unwrap();
1240 let o_as_char = o.chars().next().unwrap();
1241 match (
1242 set.iter().find(|(_, c)| s_as_char == **c),
1243 set.iter().find(|(_, c)| o_as_char == **c),
1244 ) {
1245 (Some((self_i, _)), Some((other_i, _))) => {
1246 let return_self = if getting_mininum {
1247 self_i <= other_i
1248 } else {
1249 self_i >= other_i
1250 };
1251 if return_self {
1252 Ok(self.clone())
1253 } else {
1254 Ok(other.clone())
1255 }
1256 }
1257 _ => Err(grammar_error!(
1258 UnpackingError,
1259 "Failed to find ASN1Values {self:?} and {other:?} in character set {char_set:?}",
1260 )),
1261 }
1262 }
1263 _ => Err(grammar_error!(
1264 UnpackingError,
1265 "Unsupported operation for ASN1Values {self:?} and {other:?}",
1266 )),
1267 }
1268 }
1269
1270 pub fn unwrap_as_integer(&self) -> Result<i128, GrammarError> {
1271 if let ASN1Value::Integer(i) = self {
1272 Ok(*i)
1273 } else {
1274 Err(grammar_error!(
1275 UnpackingError,
1276 "Cannot unwrap {self:?} as integer!"
1277 ))
1278 }
1279 }
1280}
1281
1282#[derive(Debug, Clone, PartialEq)]
1286pub struct DeclarationElsewhere {
1287 pub parent: Option<String>,
1289 pub identifier: String,
1290 pub constraints: Vec<Constraint>,
1291}
1292
1293impl From<(Option<&str>, &str, Option<Vec<Constraint>>)> for DeclarationElsewhere {
1294 fn from(value: (Option<&str>, &str, Option<Vec<Constraint>>)) -> Self {
1295 DeclarationElsewhere {
1296 parent: value.0.map(ToString::to_string),
1297 identifier: value.1.into(),
1298 constraints: value.2.unwrap_or_default(),
1299 }
1300 }
1301}
1302
1303#[derive(Debug, Clone, Copy, PartialEq)]
1305pub enum TagClass {
1306 Universal,
1307 Application,
1308 Private,
1309 ContextSpecific,
1310}
1311
1312#[derive(Debug, Clone, PartialEq)]
1314pub struct AsnTag {
1315 pub environment: TaggingEnvironment,
1316 pub tag_class: TagClass,
1317 pub id: u64,
1318}
1319
1320impl From<((Option<&str>, u64), Option<TaggingEnvironment>)> for AsnTag {
1321 fn from(value: ((Option<&str>, u64), Option<TaggingEnvironment>)) -> Self {
1322 let tag_class = match value.0 .0 {
1323 Some("APPLICATION") => TagClass::Application,
1324 Some("UNIVERSAL") => TagClass::Universal,
1325 Some("PRIVATE") => TagClass::Private,
1326 _ => TagClass::ContextSpecific,
1327 };
1328 AsnTag {
1329 tag_class,
1330 id: value.0 .1,
1331 environment: value.1.unwrap_or(TaggingEnvironment::Automatic),
1332 }
1333 }
1334}