asn1rs_model/model/
tag_resolver.rs1use crate::model::charset::Charset;
2use crate::model::{Asn, Definition, Model, Tag, TagProperty, Type};
3
4pub struct TagResolver<'a> {
5 model: &'a Model<Asn>,
6 scope: &'a [&'a Model<Asn>],
7}
8
9impl TagResolver<'_> {
10 pub const fn new<'a>(model: &'a Model<Asn>, scope: &'a [&'a Model<Asn>]) -> TagResolver<'a> {
11 TagResolver { model, scope }
12 }
13
14 pub fn resolve_default(ty: &Type) -> Option<Tag> {
15 let model = Model::<Asn>::default();
16 TagResolver {
17 model: &model,
18 scope: &[],
19 }
20 .resolve_type_tag(ty)
21 }
22
23 pub fn resolve_tag(&self, ty: &str) -> Option<Tag> {
26 self.model
27 .imports
28 .iter()
29 .find(|import| import.what.iter().any(|what| what.eq(ty)))
30 .map(|import| &import.from)
31 .and_then(|model_name| self.scope.iter().find(|model| model.name.eq(model_name)))
32 .and_then(|model| {
33 TagResolver {
34 model,
35 scope: self.scope,
36 }
37 .resolve_tag(ty)
38 })
39 .or_else(|| {
40 self.model.definitions.iter().find(|d| d.0.eq(ty)).and_then(
41 |Definition(_name, asn)| asn.tag.or_else(|| self.resolve_type_tag(&asn.r#type)),
42 )
43 })
44 }
45
46 pub fn resolve_no_default(&self, ty: &Type) -> Option<Tag> {
49 let default = Self::resolve_default(ty);
50 let resolved = self.resolve_type_tag(ty);
51 resolved.filter(|r| default.ne(&Some(*r)))
52 }
53
54 pub fn resolve_type_tag(&self, ty: &Type) -> Option<Tag> {
57 match ty {
58 Type::Boolean => Some(Tag::DEFAULT_BOOLEAN),
59 Type::Integer(_) => Some(Tag::DEFAULT_INTEGER),
60 Type::BitString(_) => Some(Tag::DEFAULT_BIT_STRING),
61 Type::OctetString(_) => Some(Tag::DEFAULT_OCTET_STRING),
62 Type::Enumerated(_) => Some(Tag::DEFAULT_ENUMERATED),
63 Type::String(_, Charset::Numeric) => Some(Tag::DEFAULT_NUMERIC_STRING),
64 Type::String(_, Charset::Printable) => Some(Tag::DEFAULT_PRINTABLE_STRING),
65 Type::String(_, Charset::Visible) => Some(Tag::DEFAULT_VISIBLE_STRING),
66 Type::String(_, Charset::Utf8) => Some(Tag::DEFAULT_UTF8_STRING),
67 Type::String(_, Charset::Ia5) => Some(Tag::DEFAULT_IA5_STRING),
68 Type::Null => Some(Tag::DEFAULT_NULL),
69 Type::Optional(inner) => self.resolve_type_tag(inner),
70 Type::Default(inner, ..) => self.resolve_type_tag(inner),
71 Type::Sequence(_) => Some(Tag::DEFAULT_SEQUENCE),
72 Type::SequenceOf(_, _) => Some(Tag::DEFAULT_SEQUENCE_OF),
73 Type::Set(_) => Some(Tag::DEFAULT_SET),
74 Type::SetOf(_, _) => Some(Tag::DEFAULT_SET_OF),
75 Type::Choice(choice) => {
76 let mut tags = choice
77 .variants()
78 .take(
79 choice
80 .extension_after_index()
81 .map(|extension_after| extension_after + 1)
82 .unwrap_or_else(|| choice.len()),
83 )
84 .map(|v| v.tag().or_else(|| self.resolve_type_tag(v.r#type())))
85 .collect::<Option<Vec<Tag>>>()?;
86 tags.sort();
87 if cfg!(feature = "debug-proc-macro") {
88 println!("resolved::::{:?}", tags);
89 }
90 tags.into_iter().next()
91 }
92 Type::TypeReference(inner, tag) => {
93 let tag = (*tag).or_else(|| self.resolve_tag(inner.as_str()));
94 if cfg!(feature = "debug-proc-macro") {
95 println!("resolved :: {}::Tag = {:?}", inner, tag);
96 }
97 tag
98 }
99 }
100 }
101}