1use crate::lexer::asn1_value;
2
3use super::{constraints::*, *};
4
5#[derive(Debug, Clone, PartialEq)]
6pub struct ToplevelInformationDefinition {
7 pub comments: String,
8 pub name: String,
9 pub parameterization: Option<Parameterization>,
10 pub class: Option<ClassLink>,
11 pub value: ASN1Information,
12 pub index: Option<(Rc<RefCell<ModuleReference>>, usize)>,
13}
14
15impl From<(&str, ASN1Information, &str)> for ToplevelInformationDefinition {
16 fn from(value: (&str, ASN1Information, &str)) -> Self {
17 Self {
18 comments: String::new(),
19 name: value.0.to_owned(),
20 parameterization: None,
21 class: Some(ClassLink::ByName(value.2.to_owned())),
22 value: value.1,
23 index: None,
24 }
25 }
26}
27
28#[cfg_attr(test, derive(EnumDebug))]
29#[cfg_attr(not(test), derive(Debug))]
30#[derive(Clone, PartialEq)]
31pub enum ClassLink {
32 ByName(String),
33 ByReference(InformationObjectClass),
34}
35
36impl ToplevelInformationDefinition {
37 pub fn pdu(&self) -> &ASN1Information {
38 &self.value
39 }
40}
41
42impl
43 From<(
44 Vec<&str>,
45 &str,
46 Option<Parameterization>,
47 &str,
48 InformationObjectFields,
49 )> for ToplevelInformationDefinition
50{
51 fn from(
52 value: (
53 Vec<&str>,
54 &str,
55 Option<Parameterization>,
56 &str,
57 InformationObjectFields,
58 ),
59 ) -> Self {
60 Self {
61 comments: value.0.join("\n"),
62 name: value.1.into(),
63 class: Some(ClassLink::ByName(value.3.into())),
64 parameterization: value.2,
65 value: ASN1Information::Object(InformationObject {
66 class_name: value.3.into(),
67 fields: value.4,
68 }),
69 index: None,
70 }
71 }
72}
73
74impl From<(Vec<&str>, &str, Option<Parameterization>, &str, ObjectSet)>
75 for ToplevelInformationDefinition
76{
77 fn from(value: (Vec<&str>, &str, Option<Parameterization>, &str, ObjectSet)) -> Self {
78 Self {
79 comments: value.0.join("\n"),
80 name: value.1.into(),
81 parameterization: value.2,
82 class: Some(ClassLink::ByName(value.3.into())),
83 value: ASN1Information::ObjectSet(value.4),
84 index: None,
85 }
86 }
87}
88
89impl
90 From<(
91 Vec<&str>,
92 &str,
93 Option<Parameterization>,
94 InformationObjectClass,
95 )> for ToplevelInformationDefinition
96{
97 fn from(
98 value: (
99 Vec<&str>,
100 &str,
101 Option<Parameterization>,
102 InformationObjectClass,
103 ),
104 ) -> Self {
105 Self {
106 comments: value.0.join("\n"),
107 name: value.1.into(),
108 parameterization: value.2,
109 class: None,
110 value: ASN1Information::ObjectClass(value.3),
111 index: None,
112 }
113 }
114}
115
116#[cfg_attr(test, derive(EnumDebug))]
118#[cfg_attr(not(test), derive(Debug))]
119#[derive(Clone, PartialEq)]
120pub enum ASN1Information {
121 ObjectClass(InformationObjectClass),
122 ObjectSet(ObjectSet),
123 Object(InformationObject),
124}
125
126#[cfg_attr(test, derive(EnumDebug))]
127#[cfg_attr(not(test), derive(Debug))]
128#[derive(Clone, PartialEq)]
129pub enum SyntaxExpression {
130 Required(SyntaxToken),
131 Optional(Vec<SyntaxExpression>),
132}
133
134#[cfg_attr(test, derive(EnumDebug))]
135#[cfg_attr(not(test), derive(Debug))]
136#[derive(Clone, PartialEq)]
137pub enum SyntaxApplication {
138 ObjectSetDeclaration(ObjectSet),
139 ValueReference(ASN1Value),
140 TypeReference(ASN1Type),
141 Comma,
142 Literal(String),
143 LiteralOrTypeReference(DeclarationElsewhere),
144}
145
146impl SyntaxApplication {
147 pub fn matches(
150 &self,
151 next_token: &SyntaxToken,
152 syntax: &[(bool, SyntaxToken)],
153 current_index: usize,
154 ) -> bool {
155 match (next_token, self) {
156 (SyntaxToken::Comma, SyntaxApplication::Comma) => true,
157 (SyntaxToken::Literal(t), SyntaxApplication::Literal(a)) if t == a => true,
158 (
159 SyntaxToken::Literal(t),
160 SyntaxApplication::LiteralOrTypeReference(DeclarationElsewhere {
161 identifier, ..
162 }),
163 ) if t == identifier => true,
164 (
165 SyntaxToken::Field(ObjectFieldIdentifier::MultipleValue(_)),
166 SyntaxApplication::ObjectSetDeclaration(_),
167 ) => true,
168 (
169 SyntaxToken::Field(ObjectFieldIdentifier::MultipleValue(_)),
170 SyntaxApplication::TypeReference(_),
171 ) => true,
172 (
173 SyntaxToken::Field(ObjectFieldIdentifier::MultipleValue(_)),
174 SyntaxApplication::LiteralOrTypeReference(DeclarationElsewhere {
175 identifier, ..
176 }),
177 ) => {
178 for (required, token) in &syntax[current_index + 1..] {
179 if token.as_str() == identifier {
180 return false;
181 } else if *required {
182 return true;
183 }
184 }
185 true
186 }
187 (
188 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(_)),
189 SyntaxApplication::ValueReference(_),
190 ) => true,
191 (
192 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(_)),
193 SyntaxApplication::LiteralOrTypeReference(DeclarationElsewhere {
194 identifier: lit,
195 ..
196 }),
197 )
198 | (
199 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(_)),
200 SyntaxApplication::Literal(lit),
201 ) => {
202 let val = asn1_value(lit.as_str().into());
203 match val {
204 Ok((_, ASN1Value::ElsewhereDeclaredValue { .. })) => false,
205 Ok((_, _)) => true,
206 _ => false,
207 }
208 }
209 _ => false,
210 }
211 }
212
213 pub(crate) fn as_str_or_none(&self) -> Option<&str> {
214 match self {
215 SyntaxApplication::ObjectSetDeclaration(_) => None,
216 SyntaxApplication::ValueReference(ASN1Value::ElsewhereDeclaredValue {
217 parent: None,
218 identifier,
219 })
220 | SyntaxApplication::LiteralOrTypeReference(DeclarationElsewhere {
221 parent: None,
222 identifier,
223 ..
224 })
225 | SyntaxApplication::TypeReference(ASN1Type::ElsewhereDeclaredType(
226 DeclarationElsewhere {
227 parent: None,
228 identifier,
229 ..
230 },
231 )) => Some(identifier),
232 SyntaxApplication::Literal(l) => Some(l),
233 _ => None,
234 }
235 }
236}
237
238#[cfg_attr(test, derive(EnumDebug))]
239#[cfg_attr(not(test), derive(Debug))]
240#[derive(Clone, PartialEq)]
241pub enum SyntaxToken {
242 Literal(String),
243 Comma,
244 Field(ObjectFieldIdentifier),
245}
246
247impl SyntaxToken {
248 pub fn as_str(&self) -> &str {
249 match self {
250 SyntaxToken::Literal(s) => s.as_str(),
251 SyntaxToken::Comma => ",",
252 SyntaxToken::Field(_) => self.name_or_empty(),
253 }
254 }
255
256 pub fn name_or_empty(&self) -> &str {
257 match self {
258 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(v))
259 | SyntaxToken::Field(ObjectFieldIdentifier::MultipleValue(v)) => v.as_str(),
260 _ => "",
261 }
262 }
263}
264
265impl From<ObjectFieldIdentifier> for SyntaxToken {
266 fn from(value: ObjectFieldIdentifier) -> Self {
267 Self::Field(value)
268 }
269}
270
271impl From<&str> for SyntaxToken {
272 fn from(value: &str) -> Self {
273 if value == "," {
274 Self::Comma
275 } else {
276 Self::Literal(value.into())
277 }
278 }
279}
280
281#[derive(Debug, Clone, PartialEq)]
282pub struct InformationObjectSyntax {
283 pub expressions: Vec<SyntaxExpression>,
284}
285
286impl InformationObjectSyntax {
287 pub fn flatten(&self) -> Vec<(bool, SyntaxToken)> {
293 fn iter_expressions(
294 expressions: &[SyntaxExpression],
295 optional_recursion: bool,
296 ) -> Vec<(bool, &SyntaxExpression)> {
297 expressions
298 .iter()
299 .flat_map(|x| match x {
300 SyntaxExpression::Optional(o) => iter_expressions(o, true),
301 r => vec![(!optional_recursion, r)],
302 })
303 .collect()
304 }
305
306 iter_expressions(&self.expressions, false)
307 .into_iter()
308 .map(|x| match x {
309 (is_required, SyntaxExpression::Required(r)) => (is_required, r.clone()),
310 _ => unreachable!(),
311 })
312 .collect()
313 }
314}
315
316#[derive(Debug, Clone, PartialEq)]
317pub struct InformationObjectClass {
318 pub fields: Vec<InformationObjectClassField>,
319 pub syntax: Option<InformationObjectSyntax>,
320}
321
322impl
323 From<(
324 Vec<InformationObjectClassField>,
325 Option<Vec<SyntaxExpression>>,
326 )> for InformationObjectClass
327{
328 fn from(
329 value: (
330 Vec<InformationObjectClassField>,
331 Option<Vec<SyntaxExpression>>,
332 ),
333 ) -> Self {
334 Self {
335 fields: value.0,
336 syntax: value
337 .1
338 .map(|expr| InformationObjectSyntax { expressions: expr }),
339 }
340 }
341}
342
343#[derive(Debug, Clone, PartialEq)]
344pub struct InformationObjectClassField {
345 pub identifier: ObjectFieldIdentifier,
346 pub ty: Option<ASN1Type>,
347 pub is_optional: bool,
348 pub default: Option<ASN1Value>,
349 pub is_unique: bool,
350}
351
352impl
353 From<(
354 ObjectFieldIdentifier,
355 Option<ASN1Type>,
356 Option<&str>,
357 Option<OptionalMarker>,
358 Option<ASN1Value>,
359 )> for InformationObjectClassField
360{
361 fn from(
362 value: (
363 ObjectFieldIdentifier,
364 Option<ASN1Type>,
365 Option<&str>,
366 Option<OptionalMarker>,
367 Option<ASN1Value>,
368 ),
369 ) -> Self {
370 Self {
371 identifier: value.0,
372 ty: value.1,
373 is_unique: value.2.is_some(),
374 is_optional: value.3.is_some() || value.4.is_some(),
375 default: value.4,
376 }
377 }
378}
379
380#[cfg_attr(test, derive(EnumDebug))]
381#[cfg_attr(not(test), derive(Debug))]
382#[derive(Clone, PartialEq)]
383pub enum ObjectFieldIdentifier {
384 SingleValue(String),
385 MultipleValue(String),
386}
387
388impl ObjectFieldIdentifier {
389 pub fn identifier(&self) -> &String {
390 match self {
391 ObjectFieldIdentifier::SingleValue(s) => s,
392 ObjectFieldIdentifier::MultipleValue(s) => s,
393 }
394 }
395}
396
397#[derive(Debug, Clone, PartialEq)]
398pub struct InformationObject {
399 pub class_name: String,
400 pub fields: InformationObjectFields,
401}
402
403#[cfg_attr(test, derive(EnumDebug))]
404#[cfg_attr(not(test), derive(Debug))]
405#[derive(Clone, PartialEq)]
406pub enum InformationObjectFields {
407 DefaultSyntax(Vec<InformationObjectField>),
408 CustomSyntax(Vec<SyntaxApplication>),
409}
410
411#[cfg_attr(test, derive(EnumDebug))]
412#[cfg_attr(not(test), derive(Debug))]
413#[derive(Clone, PartialEq)]
414pub enum ObjectSetValue {
415 Reference(String),
416 Inline(InformationObjectFields),
417}
418
419impl From<&str> for ObjectSetValue {
420 fn from(value: &str) -> Self {
421 Self::Reference(value.into())
422 }
423}
424
425impl From<InformationObjectFields> for ObjectSetValue {
426 fn from(value: InformationObjectFields) -> Self {
427 Self::Inline(value)
428 }
429}
430
431#[derive(Debug, Clone, PartialEq)]
432pub struct ObjectSet {
433 pub values: Vec<ObjectSetValue>,
434 pub extensible: Option<usize>,
435}
436
437impl
438 From<(
439 Vec<ObjectSetValue>,
440 Option<ExtensionMarker>,
441 Option<Vec<ObjectSetValue>>,
442 )> for ObjectSet
443{
444 fn from(
445 mut value: (
446 Vec<ObjectSetValue>,
447 Option<ExtensionMarker>,
448 Option<Vec<ObjectSetValue>>,
449 ),
450 ) -> Self {
451 let index_of_first_extension = value.0.len();
452 value.0.append(&mut value.2.unwrap_or_default());
453 ObjectSet {
454 values: value.0,
455 extensible: value.1.map(|_| index_of_first_extension),
456 }
457 }
458}
459
460#[cfg_attr(test, derive(EnumDebug))]
461#[cfg_attr(not(test), derive(Debug))]
462#[derive(Clone, PartialEq)]
463pub enum InformationObjectField {
464 TypeField(TypeField),
465 FixedValueField(FixedValueField),
466 ObjectSetField(ObjectSetField),
467}
468
469impl InformationObjectField {
470 pub fn identifier(&self) -> &String {
472 match self {
473 InformationObjectField::TypeField(f) => &f.identifier,
474 InformationObjectField::FixedValueField(f) => &f.identifier,
475 InformationObjectField::ObjectSetField(f) => &f.identifier,
476 }
477 }
478}
479
480#[derive(Debug, Clone, PartialEq)]
481pub struct FixedValueField {
482 pub identifier: String,
483 pub value: ASN1Value,
484}
485
486impl From<(ObjectFieldIdentifier, ASN1Value)> for InformationObjectField {
487 fn from(value: (ObjectFieldIdentifier, ASN1Value)) -> Self {
488 Self::FixedValueField(FixedValueField {
489 identifier: value.0.identifier().clone(),
490 value: value.1,
491 })
492 }
493}
494
495#[derive(Debug, Clone, PartialEq)]
496pub struct TypeField {
497 pub identifier: String,
498 pub ty: ASN1Type,
499}
500
501impl From<(ObjectFieldIdentifier, ASN1Type)> for InformationObjectField {
502 fn from(value: (ObjectFieldIdentifier, ASN1Type)) -> Self {
503 Self::TypeField(TypeField {
504 identifier: value.0.identifier().clone(),
505 ty: value.1,
506 })
507 }
508}
509
510#[derive(Debug, Clone, PartialEq)]
511pub struct ObjectSetField {
512 pub identifier: String,
513 pub value: ObjectSet,
514}
515
516impl From<(ObjectFieldIdentifier, ObjectSet)> for InformationObjectField {
517 fn from(value: (ObjectFieldIdentifier, ObjectSet)) -> Self {
518 Self::ObjectSetField(ObjectSetField {
519 identifier: value.0.identifier().clone(),
520 value: value.1,
521 })
522 }
523}
524
525#[derive(Debug, Clone, PartialEq)]
526pub struct InformationObjectFieldReference {
527 pub class: String,
528 pub field_path: Vec<ObjectFieldIdentifier>,
529 pub constraints: Vec<Constraint>,
530}
531
532impl InformationObjectFieldReference {
533 pub fn field_path_as_str(&self) -> String {
538 self.field_path
539 .iter()
540 .map(|o| o.identifier().clone())
541 .collect::<Vec<_>>()
542 .join("$")
543 }
544}
545
546impl From<(&str, Vec<ObjectFieldIdentifier>, Option<Vec<Constraint>>)>
547 for InformationObjectFieldReference
548{
549 fn from(value: (&str, Vec<ObjectFieldIdentifier>, Option<Vec<Constraint>>)) -> Self {
550 Self {
551 class: value.0.into(),
552 field_path: value.1,
553 constraints: value.2.unwrap_or_default(),
554 }
555 }
556}