Skip to main content

asn1_compiler/parser/asn/structs/
defs.rs

1//! ASN.1 Definitions related Structs
2use crate::tokenizer::Token;
3
4use super::types::{
5    ioc::{Asn1Object, Asn1ObjectClass, Asn1ObjectSet},
6    Asn1Type,
7};
8
9/// Struct representing an Object Class Assignment
10#[derive(Debug, Clone)]
11pub(crate) struct Asn1ObjectClassAssignment {
12    /// Class Identifier
13    pub(crate) id: String,
14
15    /// Definition
16    pub(crate) classref: Asn1ObjectClass,
17}
18
19impl Asn1ObjectClassAssignment {
20    pub(crate) fn dependent_references(&self) -> Vec<String> {
21        self.classref.dependent_references()
22    }
23}
24
25/// Struct representing Object Set Assignment
26#[derive(Debug, Clone)]
27pub(crate) struct Asn1ObjectSetAssignment {
28    /// Identifier
29    pub(crate) id: String,
30
31    pub(crate) set: Asn1ObjectSet,
32}
33
34impl Asn1ObjectSetAssignment {
35    pub(crate) fn dependent_references(&self) -> Vec<String> {
36        self.set.dependent_references()
37    }
38}
39
40/// Struct representing an Object Assignment
41#[derive(Debug, Clone)]
42pub(crate) struct Asn1ObjectAssignment {
43    ///Identifier
44    pub(crate) id: String,
45    pub(crate) object: Asn1Object,
46}
47
48#[derive(Debug, Clone)]
49pub(crate) struct Asn1TypeAssignment {
50    /// Type Identifier
51    pub(crate) id: String,
52
53    /// Type Referred to on the RHS Side of Assignment
54    pub(crate) typeref: Asn1Type,
55}
56
57/// A Value Assignment in ASN.1 Module
58///
59/// A Value Assignment in ASN.1 module looks like -
60///
61/// ```asn
62///
63///     maxnoofElements INTEGER ::= 1000
64///
65/// ```
66///
67/// A Value assginement resolves to the `id` will be used as a key when looking up for
68/// values in a given module. The 'resolved' type of the value. See [`ResolvedType`]. Actual value
69/// (refering to a value of base ASN.1 Type. See [`base_types`]). Note: When the value is
70/// 'resolved', the actual value contains one of the base type values after all constraints are
71/// validated.
72#[derive(Debug, Clone)]
73pub(crate) struct Asn1ValueAssignment {
74    /// Identifier for the value
75    pub(crate) id: String,
76
77    /// Type Reference
78    pub(crate) typeref: Asn1Type,
79
80    /// Value Text
81    pub(crate) value: String,
82}
83
84#[derive(Debug, Clone)]
85pub(crate) enum Asn1AssignmentKind {
86    Value(Asn1ValueAssignment),
87    Type(Asn1TypeAssignment),
88    Class(Asn1ObjectClassAssignment),
89    ObjectSet(Asn1ObjectSetAssignment),
90    Object(Asn1ObjectAssignment),
91}
92
93impl Asn1AssignmentKind {
94    pub fn id(&self) -> String {
95        match self {
96            Self::Value(ref v) => v.id.clone(),
97            Self::Type(ref t) => t.id.clone(),
98            Self::Class(ref c) => c.id.clone(),
99            Self::ObjectSet(ref s) => s.id.clone(),
100            Self::Object(ref o) => o.id.clone(),
101        }
102    }
103
104    pub fn dependent_references(&self) -> Vec<String> {
105        match self {
106            Self::Value(ref v) => v.typeref.dependent_references(),
107            Self::Type(ref t) => t.typeref.dependent_references(),
108            Self::Object(ref o) => vec![o.object.class.clone()],
109            Self::ObjectSet(ref s) => s.dependent_references(),
110            Self::Class(ref c) => c.dependent_references(),
111        }
112    }
113}
114
115#[derive(Debug, Clone)]
116pub(crate) struct Asn1Definition {
117    pub(crate) kind: Asn1AssignmentKind,
118    pub(crate) params: Option<DefinitionParams>,
119    pub(crate) resolved: bool,
120}
121
122// FIXME: Hack for now
123impl Asn1Definition {
124    pub fn id(&self) -> String {
125        self.kind.id()
126    }
127    // Returns a list of dependent references for a given defintion. These will be used to sort the
128    // definitions topologically, which would make error handling considerably easier when
129    // resolving those definitions
130    pub fn dependent_references(&self) -> Vec<String> {
131        self.kind.dependent_references()
132    }
133}
134
135macro_rules! is_assignment_kind {
136
137    (($fn:ident, $variant: path)) => {
138        #[allow(dead_code)]
139        impl Asn1Definition {
140            pub fn $fn(&self) -> bool {
141                if let $variant(ref _x) = self.kind {
142                    true
143                } else {
144                    false
145                }
146            }
147        }
148    };
149
150    ($($tt:tt,)*) => {
151        $(
152        is_assignment_kind!($tt);
153        )+
154    };
155}
156
157is_assignment_kind! {
158    (is_value_assignment, Asn1AssignmentKind::Value),
159    (is_type_assignment, Asn1AssignmentKind::Type),
160    (is_class_assignment, Asn1AssignmentKind::Class),
161    (is_object_set_assignment, Asn1AssignmentKind::ObjectSet),
162    (is_object_assignment, Asn1AssignmentKind::Object),
163}
164
165macro_rules! get_inner {
166
167    (($fn:ident, $variant: path, $rval: path)) => {
168        #[allow(dead_code)]
169        impl Asn1Definition {
170            pub fn $fn(&self) -> Option<$rval> {
171                if let $variant(ref x) = self.kind {
172                    Some(x.clone())
173                } else {
174                    None
175                }
176            }
177        }
178    };
179
180    ($($tt:tt,)*) => {
181        $(
182        get_inner!($tt);
183        )+
184    };
185}
186
187get_inner! {
188    (get_inner_value, Asn1AssignmentKind::Value, Asn1ValueAssignment),
189    (get_inner_type, Asn1AssignmentKind::Type, Asn1TypeAssignment),
190    (get_inner_class, Asn1AssignmentKind::Class, Asn1ObjectClassAssignment),
191    (get_inner_object_set, Asn1AssignmentKind::ObjectSet, Asn1ObjectSetAssignment),
192    (get_inner_object, Asn1AssignmentKind::Object, Asn1ObjectAssignment),
193}
194
195#[derive(Debug, PartialEq, Clone)]
196pub(crate) enum GovernerKind {
197    Type,
198    Class,
199}
200
201#[derive(Debug, PartialEq, Clone)]
202pub(crate) struct ParamGoverner {
203    pub(crate) name: String,
204    pub(crate) kind: GovernerKind,
205}
206
207#[derive(Debug, Clone)]
208pub(crate) enum DummyReferenceKind {
209    Type,
210    Value,
211    ValueSet,
212    Class,
213    Object,
214    ObjectSet,
215}
216
217#[derive(Debug, Clone)]
218pub(crate) struct ParamDummyReference {
219    pub(crate) name: String,
220    pub(crate) _kind: DummyReferenceKind,
221}
222
223#[derive(Debug, Clone)]
224pub(crate) struct DefinitionParams {
225    pub(crate) ordered: Vec<DefinitionParam>,
226    pub(crate) type_tokens: Vec<Token>,
227}
228
229#[derive(Debug, Clone)]
230pub(crate) struct DefinitionParam {
231    pub(crate) _governer: Option<ParamGoverner>,
232    pub(crate) dummyref: ParamDummyReference,
233}