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