asn1rs_model/model/
components.rs1use crate::model::lor::{Error as ResolveError, Resolved, Resolver};
2use crate::model::lor::{ResolveState, Unresolved};
3use crate::model::{Asn, Error, Field, Model, PeekableTokens, Type};
4use crate::parser::Token;
5use std::convert::TryFrom;
6use std::iter::Peekable;
7
8#[derive(Debug, Clone, PartialOrd, PartialEq)]
10pub struct ComponentTypeList<RS: ResolveState = Unresolved> {
11 pub fields: Vec<Field<Asn<RS>>>,
12 pub extension_after: Option<usize>,
13}
14
15impl<T: Iterator<Item = Token>> TryFrom<&mut Peekable<T>> for ComponentTypeList<Unresolved> {
16 type Error = Error;
17
18 fn try_from(iter: &mut Peekable<T>) -> Result<Self, Self::Error> {
19 iter.next_separator_eq_or_err('{')?;
20 let mut sequence = Self {
21 fields: Vec::default(),
22 extension_after: None,
23 };
24
25 loop {
26 let continues = if iter.next_is_separator_and_eq('}') {
27 false
28 } else if iter.next_is_separator_and_eq('.') {
29 iter.next_separator_eq_or_err('.')?;
30 iter.next_separator_eq_or_err('.')?;
31 let field_len = sequence.fields.len();
32 sequence.extension_after = Some(field_len.saturating_sub(1));
33
34 match iter.next_or_err()? {
35 token if token.eq_separator(',') => true,
36 token if token.eq_separator('}') => false,
37 token => return Err(Error::unexpected_token(token)),
38 }
39 } else {
40 let (field, continues) = Model::<Asn<Unresolved>>::read_field(iter)?;
41 sequence.fields.push(field);
42 continues
43 };
44
45 if !continues {
46 break;
47 }
48 }
49
50 Ok(sequence)
51 }
52}
53
54impl ComponentTypeList<Unresolved> {
55 pub fn try_resolve<
56 R: Resolver<<Resolved as ResolveState>::SizeType>
57 + Resolver<<Resolved as ResolveState>::RangeType>
58 + Resolver<<Resolved as ResolveState>::ConstType>
59 + Resolver<Type<Unresolved>>,
60 >(
61 &self,
62 resolver: &R,
63 ) -> Result<ComponentTypeList<Resolved>, ResolveError> {
64 Ok(ComponentTypeList {
65 fields: self
66 .fields
67 .iter()
68 .map(|f| f.try_resolve(resolver))
69 .collect::<Result<Vec<_>, _>>()?,
70 extension_after: self.extension_after,
71 })
72 }
73}