rasn_compiler/intermediate/
types.rs

1//! `types` contains representations for ASN.1's basic types, such as `BOOLEAN`s
2//! or `SEQUENCE`s.
3#[cfg(test)]
4use internal_macros::EnumDebug;
5use std::vec;
6
7use super::{constraints::*, *};
8
9/// Trait shared by ASN1 `SET`, `SEQUENCE`, AND `CHOICE` that allows iterating
10/// over their field types.
11pub trait IterNameTypes {
12    fn iter_name_types(&self) -> impl Iterator<Item = (&str, &ASN1Type)>;
13}
14
15/// Trait shared by all ASN1 types that can be constrained a.k.a subtyped.
16/// *See also Rec. ITU-T X.680 (02/2021) §49 - §51*
17pub trait Constrainable {
18    /// returns a reference to the type's constraints
19    fn constraints(&self) -> &Vec<Constraint>;
20    /// returns a mutable reference to the type's constraints
21    fn constraints_mut(&mut self) -> &mut Vec<Constraint>;
22}
23
24macro_rules! constrainable {
25    ($typ:ty) => {
26        impl Constrainable for $typ {
27            fn constraints(&self) -> &Vec<Constraint> {
28                &self.constraints
29            }
30
31            fn constraints_mut(&mut self) -> &mut Vec<Constraint> {
32                &mut self.constraints
33            }
34        }
35    };
36}
37
38constrainable!(Boolean);
39constrainable!(Integer);
40constrainable!(BitString);
41constrainable!(OctetString);
42constrainable!(CharacterString);
43constrainable!(Real);
44constrainable!(SequenceOrSet);
45constrainable!(SequenceOrSetOf);
46constrainable!(Choice);
47constrainable!(Enumerated);
48constrainable!(DeclarationElsewhere);
49constrainable!(InformationObjectFieldReference);
50constrainable!(Time);
51
52/// Representation of an ASN1 BOOLEAN data element
53/// with corresponding constraints.
54/// *As defined in Rec. ITU-T X.680 (02/2021) §18*
55#[derive(Debug, Clone, PartialEq, Default)]
56pub struct Boolean {
57    pub constraints: Vec<Constraint>,
58}
59
60impl From<Option<Vec<Constraint>>> for Boolean {
61    fn from(value: Option<Vec<Constraint>>) -> Self {
62        Self {
63            constraints: value.unwrap_or_default(),
64        }
65    }
66}
67
68/// Representation of an ASN1 INTEGER data element
69/// with corresponding constraints and distinguished values.
70/// *As defined in Rec. ITU-T X.680 (02/2021) §19*
71#[derive(Debug, Clone, PartialEq, Default)]
72pub struct Integer {
73    pub constraints: Vec<Constraint>,
74    pub distinguished_values: Option<Vec<DistinguishedValue>>,
75}
76
77impl Integer {
78    /// Returns the [IntegerType] of `self`.
79    /// The [IntegerType] describes the absolute range of an integer
80    pub fn int_type(&self) -> IntegerType {
81        self.constraints
82            .iter()
83            .fold(IntegerType::Unbounded, |acc, c| {
84                c.integer_constraints().max_restrictive(acc)
85            })
86    }
87}
88
89impl From<(i128, i128, bool)> for Integer {
90    fn from(value: (i128, i128, bool)) -> Self {
91        Self {
92            constraints: vec![Constraint::SubtypeConstraint(ElementSet {
93                set: ElementOrSetOperation::Element(SubtypeElement::ValueRange {
94                    min: Some(ASN1Value::Integer(value.0)),
95                    max: Some(ASN1Value::Integer(value.1)),
96                    extensible: value.2,
97                }),
98                extensible: value.2,
99            })],
100            distinguished_values: None,
101        }
102    }
103}
104
105impl From<(Option<i128>, Option<i128>, bool)> for Integer {
106    fn from(value: (Option<i128>, Option<i128>, bool)) -> Self {
107        Self {
108            constraints: vec![Constraint::SubtypeConstraint(ElementSet {
109                set: ElementOrSetOperation::Element(SubtypeElement::ValueRange {
110                    min: value.0.map(ASN1Value::Integer),
111                    max: value.1.map(ASN1Value::Integer),
112                    extensible: value.2,
113                }),
114                extensible: value.2,
115            })],
116            distinguished_values: None,
117        }
118    }
119}
120
121impl
122    From<(
123        &str,
124        Option<Vec<DistinguishedValue>>,
125        Option<Vec<Constraint>>,
126    )> for Integer
127{
128    fn from(
129        value: (
130            &str,
131            Option<Vec<DistinguishedValue>>,
132            Option<Vec<Constraint>>,
133        ),
134    ) -> Self {
135        Self {
136            constraints: value.2.unwrap_or_default(),
137            distinguished_values: value.1,
138        }
139    }
140}
141
142/// Representation of an ASN1 REAL data element
143/// with corresponding constraints.
144/// *As defined in Rec. ITU-T X.680 (02/2021) §21*
145#[derive(Debug, Clone, PartialEq)]
146pub struct Real {
147    pub constraints: Vec<Constraint>,
148}
149
150impl From<Option<Vec<Constraint>>> for Real {
151    fn from(value: Option<Vec<Constraint>>) -> Self {
152        Self {
153            constraints: value.unwrap_or_default(),
154        }
155    }
156}
157
158/// Representation of an ASN1 GeneralizedTime data element
159/// with corresponding constraints.
160/// *As defined in Rec. ITU-T X.680 (02/2021) §46*
161#[derive(Debug, Clone, PartialEq)]
162pub struct GeneralizedTime {
163    pub constraints: Vec<Constraint>,
164}
165
166/// Representation of an ASN1 Universal time (a.k.a UTCTime)
167/// data element with corresponding constraints.
168/// *As defined in Rec. ITU-T X.680 (02/2021) §47*
169#[derive(Debug, Clone, PartialEq)]
170pub struct UTCTime {
171    pub constraints: Vec<Constraint>,
172}
173
174/// Representation of an ASN1 OCTET STRING data element
175/// with corresponding constraints.
176/// *As defined in Rec. ITU-T X.680 (02/2021) §23*
177#[derive(Debug, Clone, PartialEq)]
178pub struct OctetString {
179    pub constraints: Vec<Constraint>,
180}
181
182impl From<Option<Vec<Constraint>>> for OctetString {
183    fn from(value: Option<Vec<Constraint>>) -> Self {
184        OctetString {
185            constraints: value.unwrap_or_default(),
186        }
187    }
188}
189
190/// Representation of an ASN1 BIT STRING data element
191/// with corresponding constraints and distinguished values
192/// defining the individual bits.
193/// *As defined in Rec. ITU-T X.680 (02/2021) §22*
194#[derive(Debug, Clone, PartialEq)]
195pub struct BitString {
196    pub constraints: Vec<Constraint>,
197    pub distinguished_values: Option<Vec<DistinguishedValue>>,
198}
199
200impl From<(Option<Vec<DistinguishedValue>>, Option<Vec<Constraint>>)> for BitString {
201    fn from(value: (Option<Vec<DistinguishedValue>>, Option<Vec<Constraint>>)) -> Self {
202        BitString {
203            constraints: value.1.unwrap_or_default(),
204            distinguished_values: value.0,
205        }
206    }
207}
208
209/// Representation of an ASN1 OBJECT IDENTIFIER data element
210/// with corresponding constraints.
211/// *As defined in Rec. ITU-T X.680 (02/2021) §32*
212#[derive(Debug, Clone, PartialEq)]
213pub struct ObjectIdentifier {
214    pub constraints: Vec<Constraint>,
215}
216
217impl From<Option<Vec<Constraint>>> for ObjectIdentifier {
218    fn from(value: Option<Vec<Constraint>>) -> Self {
219        ObjectIdentifier {
220            constraints: value.unwrap_or_default(),
221        }
222    }
223}
224
225/// Representation of an ASN1 TIME data element
226/// with corresponding constraints.
227/// *As defined in Rec. ITU-T X.680 (02/2021) §38*
228#[derive(Debug, Clone, PartialEq)]
229pub struct Time {
230    pub constraints: Vec<Constraint>,
231}
232
233impl From<Option<Vec<Constraint>>> for Time {
234    fn from(value: Option<Vec<Constraint>>) -> Self {
235        Time {
236            constraints: value.unwrap_or_default(),
237        }
238    }
239}
240
241/// Representation of an ASN1 Character String type data element
242/// with corresponding constraints. ASN1 Character String types
243/// include IA5String, UTF8String, VideotexString.
244/// *As defined in Rec. ITU-T X.680 (02/2021) §39-*§44
245#[derive(Debug, Clone, PartialEq)]
246pub struct CharacterString {
247    pub constraints: Vec<Constraint>,
248    pub ty: CharacterStringType,
249}
250
251impl From<(&str, Option<Vec<Constraint>>)> for CharacterString {
252    fn from(value: (&str, Option<Vec<Constraint>>)) -> Self {
253        CharacterString {
254            constraints: value.1.unwrap_or_default(),
255            ty: value.0.into(),
256        }
257    }
258}
259
260/// Representation of an ASN1 SEQUENCE OF and SET OF data element
261/// with corresponding constraints and element type info
262/// Whether the struct describes a SEQUENCE OF or a SET OF
263/// is identified by the `ASN1Type` enum variant that
264/// holds this struct as a value (i.e. `ASN1Type::SetOf(SequenceOrSetOf { .. })`
265/// or `ASN1Type::SequenceOf(SequenceOrSetOf { .. })`).
266/// *As defined in Rec. ITU-T X.680 (02/2021) §26 and §28*
267#[derive(Debug, Clone, PartialEq)]
268pub struct SequenceOrSetOf {
269    pub constraints: Vec<Constraint>,
270    /// [ASN.1 type](ASN1Type) of the individual elements of the collection
271    /// ### Example
272    /// The ASN.1 type
273    /// ```ignore
274    /// Sequence-of-booleans ::= SEQUENCE OF BOOLEAN
275    /// ```
276    /// will have an `element_type` field of
277    /// ```
278    /// # use rasn_compiler::prelude::ir::*;
279    /// # let test =
280    /// Box::new(ASN1Type::Boolean(Boolean { constraints: vec![] } ))
281    /// # ;
282    /// ```
283    pub element_type: Box<ASN1Type>,
284    pub is_recursive: bool,
285}
286
287impl From<(Option<Vec<Constraint>>, ASN1Type)> for SequenceOrSetOf {
288    fn from(value: (Option<Vec<Constraint>>, ASN1Type)) -> Self {
289        Self {
290            constraints: value.0.unwrap_or_default(),
291            element_type: Box::new(value.1),
292            is_recursive: false,
293        }
294    }
295}
296
297/// Representation of an ASN1 SEQUENCE or SET data element
298/// with corresponding members and extension information.
299/// Whether the struct describes a SEQUENCE or a SET
300/// is identified by the `ASN1Type` enum variant that
301/// holds this struct as a value (i.e. `ASN1Type::Set(SequenceOrSet { .. })`
302/// or `ASN1Type::Sequence(SequenceOrSet { .. })`).
303/// *As defined in Rec. ITU-T X.680 (02/2021) §25 and §27*
304#[derive(Debug, Clone, PartialEq)]
305pub struct SequenceOrSet {
306    pub components_of: Vec<String>,
307    pub extensible: Option<usize>,
308    pub constraints: Vec<Constraint>,
309    pub members: Vec<SequenceOrSetMember>,
310}
311
312impl IterNameTypes for SequenceOrSet {
313    fn iter_name_types(&self) -> impl Iterator<Item = (&str, &ASN1Type)> {
314        self.members.iter().map(|m| (m.name.as_str(), &m.ty))
315    }
316}
317
318impl
319    From<(
320        (
321            Vec<SequenceComponent>,
322            Option<ExtensionMarker>,
323            Option<Vec<SequenceComponent>>,
324        ),
325        Option<Vec<Constraint>>,
326    )> for SequenceOrSet
327{
328    fn from(
329        mut value: (
330            (
331                Vec<SequenceComponent>,
332                Option<ExtensionMarker>,
333                Option<Vec<SequenceComponent>>,
334            ),
335            Option<Vec<Constraint>>,
336        ),
337    ) -> Self {
338        let index_of_first_extension = value.0 .0.len();
339        value.0 .0.append(&mut value.0 .2.unwrap_or_default());
340        let mut components_of = vec![];
341        let mut members = vec![];
342        for comp in value.0 .0 {
343            match comp {
344                SequenceComponent::Member(m) => members.push(m),
345                SequenceComponent::ComponentsOf(c) => components_of.push(c),
346            }
347        }
348        SequenceOrSet {
349            components_of,
350            constraints: value.1.unwrap_or_default(),
351            extensible: value.0 .1.map(|_| index_of_first_extension),
352            members,
353        }
354    }
355}
356
357impl
358    From<(
359        (
360            Vec<SequenceOrSetMember>,
361            Option<ExtensionMarker>,
362            Option<Vec<SequenceOrSetMember>>,
363        ),
364        Option<Vec<Constraint>>,
365    )> for SequenceOrSet
366{
367    fn from(
368        mut value: (
369            (
370                Vec<SequenceOrSetMember>,
371                Option<ExtensionMarker>,
372                Option<Vec<SequenceOrSetMember>>,
373            ),
374            Option<Vec<Constraint>>,
375        ),
376    ) -> Self {
377        let index_of_first_extension = value.0 .0.len();
378        value.0 .0.append(&mut value.0 .2.unwrap_or_default());
379        SequenceOrSet {
380            components_of: vec![],
381            constraints: value.1.unwrap_or_default(),
382            extensible: value.0 .1.map(|_| index_of_first_extension),
383            members: value.0 .0,
384        }
385    }
386}
387
388/// Intermediate parsing type to parse COMPONENTS OF notation.
389/// `SequenceComponent` is an intermediary type that implementors of
390/// a [Backend] will usually not interact with.
391/// When parsing the body of an ASN.1 SEQUENCE or SET, the lexer
392/// distinguishes between a group of members (`SequenceComponent::ComponentsOf`) that is imnported from
393/// another ASN.1 data element using the `COMPONENTS OF` notation
394/// (i.e. `Extending-Sequence ::= SEQUENCE { COMPONENTS OF Another-Sequence, added-field BOOLEAN }`)
395/// and the regular member declaration (`SequenceComponent::Member`)
396/// (i.e. `Simple-Sequence ::= SEQUENCE { field BOOLEAN }`).
397/// When the lexer assembles the complete [SequenceOrSet] struct,
398/// it groups the parsed `SequenceComponent` items into the `members`
399/// and `components_of` fields of the [SequenceOrSet] struct. The linker
400/// will subsequently try to resolve the `components_of` identifiers.
401#[cfg_attr(test, derive(EnumDebug))]
402#[cfg_attr(not(test), derive(Debug))]
403#[derive(Clone, PartialEq)]
404pub enum SequenceComponent {
405    Member(SequenceOrSetMember),
406    ComponentsOf(String),
407}
408
409/// Representation of an single ASN1 SEQUENCE or SET member.
410/// ### Example
411/// The ASN.1 SEQUENCE defined as
412/// ```ignore
413/// Test-Sequence ::= SEQUENCE {
414///     int-member [0] INTEGER (0..2) DEFAULT 1
415/// }
416/// ```
417/// defines one member, which is representated as follows
418/// ```
419/// # use rasn_compiler::prelude::ir::*;
420/// # let test =
421/// SequenceOrSetMember {
422///     is_recursive: false,
423///     name: String::from("int-member"),
424///     tag: Some(AsnTag {
425///         environment: TaggingEnvironment::Automatic,
426///         tag_class: TagClass::ContextSpecific,
427///         id: 0,
428///     }),
429///     ty: ASN1Type::Integer(Integer {
430///         constraints: vec![
431///             Constraint::SubtypeConstraint(ElementSet {
432///                 set: ElementOrSetOperation::Element(SubtypeElement::ValueRange {
433///                     min: Some(ASN1Value::Integer(0)),
434///                     max: Some(ASN1Value::Integer(2)),
435///                     extensible: false
436///                 }),
437///                 extensible: false
438///            })
439///         ],
440///         distinguished_values: None,
441///     }),
442///     default_value: Some(ASN1Value::Integer(1)),
443///     is_optional: true,
444///     constraints: vec![]
445/// }
446/// # ;
447/// ```
448#[derive(Debug, Clone, PartialEq)]
449pub struct SequenceOrSetMember {
450    pub name: String,
451    pub tag: Option<AsnTag>,
452    pub ty: ASN1Type,
453    pub default_value: Option<ASN1Value>,
454    pub is_optional: bool,
455    pub is_recursive: bool,
456    pub constraints: Vec<Constraint>,
457}
458
459impl
460    From<(
461        &str,
462        Option<AsnTag>,
463        ASN1Type,
464        Option<Vec<Constraint>>,
465        Option<OptionalMarker>,
466        Option<ASN1Value>,
467    )> for SequenceOrSetMember
468{
469    fn from(
470        value: (
471            &str,
472            Option<AsnTag>,
473            ASN1Type,
474            Option<Vec<Constraint>>,
475            Option<OptionalMarker>,
476            Option<ASN1Value>,
477        ),
478    ) -> Self {
479        SequenceOrSetMember {
480            name: value.0.into(),
481            tag: value.1,
482            ty: value.2,
483            is_optional: value.4.is_some() || value.5.is_some(),
484            default_value: value.5,
485            is_recursive: false,
486            constraints: value.3.unwrap_or_default(),
487        }
488    }
489}
490
491/// Representation of an ASN1 CHOICE data element
492/// with corresponding members and extension information.
493/// *As defined in Rec. ITU-T X.680 (02/2021) §29*
494#[derive(Debug, Clone, PartialEq)]
495pub struct Choice {
496    pub extensible: Option<usize>,
497    pub options: Vec<ChoiceOption>,
498    pub constraints: Vec<Constraint>,
499}
500
501impl IterNameTypes for Choice {
502    fn iter_name_types(&self) -> impl Iterator<Item = (&str, &ASN1Type)> {
503        self.options.iter().map(|o| (o.name.as_str(), &o.ty))
504    }
505}
506
507impl
508    From<(
509        Vec<ChoiceOption>,
510        Option<ExtensionMarker>,
511        Option<Vec<ChoiceOption>>,
512    )> for Choice
513{
514    fn from(
515        mut value: (
516            Vec<ChoiceOption>,
517            Option<ExtensionMarker>,
518            Option<Vec<ChoiceOption>>,
519        ),
520    ) -> Self {
521        let index_of_first_extension = value.0.len();
522        value.0.append(&mut value.2.unwrap_or_default());
523        Choice {
524            extensible: value.1.map(|_| index_of_first_extension),
525            options: value.0,
526            constraints: vec![],
527        }
528    }
529}
530
531/// Representation of an single ASN1 CHOICE option.
532/// ### Example
533/// The ASN.1 CHOICE defined as
534/// ```ignore
535/// Test-Choice ::= CHOICE {
536///     boolean-option [0] BOOLEAN
537/// }
538/// ```
539/// defines one option, which is representated as follows
540/// ```
541/// # use rasn_compiler::prelude::ir::*;
542/// # let test =
543/// ChoiceOption {
544///     name: String::from("boolean-option"),
545///     is_recursive: false,
546///     tag: Some(AsnTag {
547///         environment: TaggingEnvironment::Automatic,
548///         tag_class: TagClass::ContextSpecific,
549///         id: 0,
550///     }),
551///     ty: ASN1Type::Boolean(Boolean {
552///         constraints: vec![]
553///     }),
554///     constraints: vec![]
555/// }
556/// # ;
557/// ```
558#[derive(Debug, Clone, PartialEq)]
559pub struct ChoiceOption {
560    pub name: String,
561    pub tag: Option<AsnTag>,
562    pub ty: ASN1Type,
563    pub constraints: Vec<Constraint>,
564    pub is_recursive: bool,
565}
566
567impl From<(&str, Option<AsnTag>, ASN1Type, Option<Vec<Constraint>>)> for ChoiceOption {
568    fn from(value: (&str, Option<AsnTag>, ASN1Type, Option<Vec<Constraint>>)) -> Self {
569        ChoiceOption {
570            name: value.0.into(),
571            tag: value.1,
572            ty: value.2,
573            constraints: value.3.unwrap_or_default(),
574            is_recursive: false,
575        }
576    }
577}
578
579/// Representation of an ASN1 ENUMERATED data element
580/// with corresponding enumerals and extension information.
581/// *As defined in Rec. ITU-T X.680 (02/2021) §20*
582#[derive(Debug, Clone, PartialEq)]
583pub struct Enumerated {
584    pub members: Vec<Enumeral>,
585    pub extensible: Option<usize>,
586    pub constraints: Vec<Constraint>,
587}
588
589impl
590    From<(
591        Vec<Enumeral>,
592        Option<ExtensionMarker>,
593        Option<Vec<Enumeral>>,
594    )> for Enumerated
595{
596    fn from(
597        mut value: (
598            Vec<Enumeral>,
599            Option<ExtensionMarker>,
600            Option<Vec<Enumeral>>,
601        ),
602    ) -> Self {
603        let index_of_first_extension = value.0.len();
604        value.0.append(&mut value.2.unwrap_or_default());
605        Enumerated {
606            members: value.0,
607            extensible: value.1.map(|_| index_of_first_extension),
608            constraints: vec![],
609        }
610    }
611}
612
613/// Representation of a single member/enumeral of an ASN1
614/// ENUMERATED data element.
615/// ### Example
616/// The ASN.1 ENUMERATED defined as
617/// ```ignore
618/// Test-Enum ::= ENUMERATED {
619///     first-item(7) -- This is the first item of Test-Enum
620/// }
621/// ```
622/// defines one option, which is representated as follows
623/// ```
624/// # use rasn_compiler::prelude::ir::*;
625/// # let test =
626/// Enumeral {
627///     name: String::from("first-item"),
628///     description: Some(String::from(" This is the first item of Test-Enum")),
629///     index: 7
630/// }
631/// # ;
632/// ```
633#[derive(Debug, Clone, PartialEq)]
634pub struct Enumeral {
635    pub name: String,
636    pub description: Option<String>,
637    pub index: i128,
638}
639
640/// Representation of a ASN1 distinguished value,
641/// as seen in some INTEGER and BIT STRING declarations
642/// *As defined in Rec. ITU-T X.680 (02/2021) §19.5 and §22.4*
643#[derive(Debug, Clone, PartialEq)]
644pub struct DistinguishedValue {
645    pub name: String,
646    pub value: i128,
647}
648
649impl From<(&str, i128)> for DistinguishedValue {
650    fn from(value: (&str, i128)) -> Self {
651        Self {
652            name: value.0.into(),
653            value: value.1,
654        }
655    }
656}
657
658/// Representation of a ASN1 selection type as used with ASN1 CHOICEs
659/// *As defined in Rec. ITU-T X.680 (02/2021) §30*
660#[derive(Debug, Clone, PartialEq)]
661pub struct ChoiceSelectionType {
662    pub choice_name: String,
663    pub selected_option: String,
664}
665
666impl From<(&str, &str)> for ChoiceSelectionType {
667    fn from(value: (&str, &str)) -> Self {
668        Self {
669            choice_name: value.1.into(),
670            selected_option: value.0.into(),
671        }
672    }
673}