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