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 parent: None,
213 identifier,
214 })
215 | SyntaxApplication::LiteralOrTypeReference(DeclarationElsewhere {
216 parent: None,
217 identifier,
218 ..
219 })
220 | SyntaxApplication::TypeReference(ASN1Type::ElsewhereDeclaredType(
221 DeclarationElsewhere {
222 parent: None,
223 identifier,
224 ..
225 },
226 )) => Some(identifier),
227 SyntaxApplication::Literal(l) => Some(l),
228 _ => None,
229 }
230 }
231}
232
233#[cfg_attr(test, derive(EnumDebug))]
234#[cfg_attr(not(test), derive(Debug))]
235#[derive(Clone, PartialEq)]
236pub enum SyntaxToken {
237 Literal(String),
238 Comma,
239 Field(ObjectFieldIdentifier),
240}
241
242impl SyntaxToken {
243 pub fn as_str(&self) -> &str {
244 match self {
245 SyntaxToken::Literal(s) => s.as_str(),
246 SyntaxToken::Comma => ",",
247 SyntaxToken::Field(_) => self.name_or_empty(),
248 }
249 }
250
251 pub fn name_or_empty(&self) -> &str {
252 match self {
253 SyntaxToken::Field(ObjectFieldIdentifier::SingleValue(v))
254 | SyntaxToken::Field(ObjectFieldIdentifier::MultipleValue(v)) => v.as_str(),
255 _ => "",
256 }
257 }
258}
259
260impl From<ObjectFieldIdentifier> for SyntaxToken {
261 fn from(value: ObjectFieldIdentifier) -> Self {
262 Self::Field(value)
263 }
264}
265
266impl From<&str> for SyntaxToken {
267 fn from(value: &str) -> Self {
268 if value == "," {
269 Self::Comma
270 } else {
271 Self::Literal(value.into())
272 }
273 }
274}
275
276#[derive(Debug, Clone, PartialEq)]
277pub struct InformationObjectSyntax {
278 pub expressions: Vec<SyntaxExpression>,
279}
280
281impl InformationObjectSyntax {
282 pub fn flatten(&self) -> Vec<(bool, SyntaxToken)> {
288 fn iter_expressions(
289 expressions: &[SyntaxExpression],
290 optional_recursion: bool,
291 ) -> Vec<(bool, &SyntaxExpression)> {
292 expressions
293 .iter()
294 .flat_map(|x| match x {
295 SyntaxExpression::Optional(o) => iter_expressions(o, true),
296 r => vec![(!optional_recursion, r)],
297 })
298 .collect()
299 }
300
301 iter_expressions(&self.expressions, false)
302 .into_iter()
303 .map(|x| match x {
304 (is_required, SyntaxExpression::Required(r)) => (is_required, r.clone()),
305 _ => unreachable!(),
306 })
307 .collect()
308 }
309}
310
311#[derive(Debug, Clone, PartialEq)]
316pub struct ObjectClassDefn {
317 pub fields: Vec<InformationObjectClassField>,
319 pub syntax: Option<InformationObjectSyntax>,
321}
322
323impl
324 From<(
325 Vec<InformationObjectClassField>,
326 Option<Vec<SyntaxExpression>>,
327 )> for ObjectClassDefn
328{
329 fn from(
330 value: (
331 Vec<InformationObjectClassField>,
332 Option<Vec<SyntaxExpression>>,
333 ),
334 ) -> Self {
335 Self {
336 fields: value.0,
337 syntax: value
338 .1
339 .map(|expr| InformationObjectSyntax { expressions: expr }),
340 }
341 }
342}
343
344#[derive(Debug, Clone, PartialEq)]
345pub struct InformationObjectClassField {
346 pub identifier: ObjectFieldIdentifier,
347 pub ty: Option<ASN1Type>,
348 pub optionality: Optionality<ASN1Value>,
349 pub is_unique: bool,
350}
351
352impl
353 From<(
354 ObjectFieldIdentifier,
355 Option<ASN1Type>,
356 Option<&str>,
357 Optionality<ASN1Value>,
358 )> for InformationObjectClassField
359{
360 fn from(
361 value: (
362 ObjectFieldIdentifier,
363 Option<ASN1Type>,
364 Option<&str>,
365 Optionality<ASN1Value>,
366 ),
367 ) -> Self {
368 Self {
369 identifier: value.0,
370 ty: value.1,
371 is_unique: value.2.is_some(),
372 optionality: value.3,
373 }
374 }
375}
376
377#[cfg_attr(test, derive(EnumDebug))]
378#[cfg_attr(not(test), derive(Debug))]
379#[derive(Clone, PartialEq)]
380pub enum ObjectFieldIdentifier {
381 SingleValue(String),
382 MultipleValue(String),
383}
384
385impl ObjectFieldIdentifier {
386 pub fn identifier(&self) -> &String {
387 match self {
388 ObjectFieldIdentifier::SingleValue(s) => s,
389 ObjectFieldIdentifier::MultipleValue(s) => s,
390 }
391 }
392}
393
394#[derive(Debug, Clone, PartialEq)]
395pub struct InformationObject {
396 pub class_name: String,
397 pub fields: InformationObjectFields,
398}
399
400#[cfg_attr(test, derive(EnumDebug))]
401#[cfg_attr(not(test), derive(Debug))]
402#[derive(Clone, PartialEq)]
403pub enum InformationObjectFields {
404 DefaultSyntax(Vec<InformationObjectField>),
405 CustomSyntax(Vec<SyntaxApplication>),
406}
407
408#[cfg_attr(test, derive(EnumDebug))]
409#[cfg_attr(not(test), derive(Debug))]
410#[derive(Clone, PartialEq)]
411pub enum ObjectSetValue {
412 Reference(String),
413 Inline(InformationObjectFields),
414}
415
416impl From<&str> for ObjectSetValue {
417 fn from(value: &str) -> Self {
418 Self::Reference(value.into())
419 }
420}
421
422impl From<InformationObjectFields> for ObjectSetValue {
423 fn from(value: InformationObjectFields) -> Self {
424 Self::Inline(value)
425 }
426}
427
428#[derive(Debug, Clone, PartialEq)]
429pub struct ObjectSet {
430 pub values: Vec<ObjectSetValue>,
431 pub extensible: Option<usize>,
432}
433
434impl
435 From<(
436 Vec<ObjectSetValue>,
437 Option<ExtensionMarker>,
438 Option<Vec<ObjectSetValue>>,
439 )> for ObjectSet
440{
441 fn from(
442 mut value: (
443 Vec<ObjectSetValue>,
444 Option<ExtensionMarker>,
445 Option<Vec<ObjectSetValue>>,
446 ),
447 ) -> Self {
448 let index_of_first_extension = value.0.len();
449 value.0.append(&mut value.2.unwrap_or_default());
450 ObjectSet {
451 values: value.0,
452 extensible: value.1.map(|_| index_of_first_extension),
453 }
454 }
455}
456
457#[cfg_attr(test, derive(EnumDebug))]
458#[cfg_attr(not(test), derive(Debug))]
459#[derive(Clone, PartialEq)]
460pub enum InformationObjectField {
461 TypeField(TypeField),
462 FixedValueField(FixedValueField),
463 ObjectSetField(ObjectSetField),
464}
465
466impl InformationObjectField {
467 pub fn identifier(&self) -> &String {
469 match self {
470 InformationObjectField::TypeField(f) => &f.identifier,
471 InformationObjectField::FixedValueField(f) => &f.identifier,
472 InformationObjectField::ObjectSetField(f) => &f.identifier,
473 }
474 }
475}
476
477#[derive(Debug, Clone, PartialEq)]
478pub struct FixedValueField {
479 pub identifier: String,
480 pub value: ASN1Value,
481}
482
483impl From<(ObjectFieldIdentifier, ASN1Value)> for InformationObjectField {
484 fn from(value: (ObjectFieldIdentifier, ASN1Value)) -> Self {
485 Self::FixedValueField(FixedValueField {
486 identifier: value.0.identifier().clone(),
487 value: value.1,
488 })
489 }
490}
491
492#[derive(Debug, Clone, PartialEq)]
493pub struct TypeField {
494 pub identifier: String,
495 pub ty: ASN1Type,
496}
497
498impl From<(ObjectFieldIdentifier, ASN1Type)> for InformationObjectField {
499 fn from(value: (ObjectFieldIdentifier, ASN1Type)) -> Self {
500 Self::TypeField(TypeField {
501 identifier: value.0.identifier().clone(),
502 ty: value.1,
503 })
504 }
505}
506
507#[derive(Debug, Clone, PartialEq)]
508pub struct ObjectSetField {
509 pub identifier: String,
510 pub value: ObjectSet,
511}
512
513impl From<(ObjectFieldIdentifier, ObjectSet)> for InformationObjectField {
514 fn from(value: (ObjectFieldIdentifier, ObjectSet)) -> Self {
515 Self::ObjectSetField(ObjectSetField {
516 identifier: value.0.identifier().clone(),
517 value: value.1,
518 })
519 }
520}
521
522#[derive(Debug, Clone, PartialEq)]
526pub struct ObjectClassFieldType {
527 pub class: String,
528 pub field_path: Vec<ObjectFieldIdentifier>,
529 pub constraints: Vec<Constraint>,
530}
531
532impl ObjectClassFieldType {
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>>)> for ObjectClassFieldType {
547 fn from(value: (&str, Vec<ObjectFieldIdentifier>, Option<Vec<Constraint>>)) -> Self {
548 Self {
549 class: value.0.into(),
550 field_path: value.1,
551 constraints: value.2.unwrap_or_default(),
552 }
553 }
554}