asn1rs_model/model/
int.rs1use crate::model::lor::Error as ResolveError;
2use crate::model::lor::{ResolveState, Resolver, TryResolve, Unresolved};
3use crate::model::{Asn, Error, LitOrRef, Model, PeekableTokens, Range};
4use crate::parser::Token;
5use std::convert::TryFrom;
6use std::fmt::{Debug, Display};
7use std::iter::Peekable;
8
9#[derive(Default, Debug, Clone, PartialOrd, PartialEq, Eq)]
10pub struct Integer<T: Display + Debug + Clone = i64> {
11 pub range: Range<Option<T>>,
12 pub constants: Vec<(String, i64)>,
13}
14
15impl<T: Display + Debug + Clone> Integer<T> {
16 pub fn with_range(range: Range<Option<T>>) -> Self {
17 Self {
18 range,
19 constants: Vec::default(),
20 }
21 }
22}
23
24impl<T: Iterator<Item = Token>> TryFrom<&mut Peekable<T>>
25 for Integer<<Unresolved as ResolveState>::RangeType>
26{
27 type Error = Error;
28
29 fn try_from(iter: &mut Peekable<T>) -> Result<Self, Self::Error> {
30 let constants =
31 Model::<Asn>::maybe_read_constants(iter, Model::<Asn>::constant_i64_parser)?;
32 let range = if iter.next_is_separator_and_eq('(') {
33 let start = iter.next_or_err()?;
34 iter.next_separator_eq_or_err('.')?;
35 iter.next_separator_eq_or_err('.')?;
36 let end = iter.next_or_err()?;
37 let extensible = if iter.next_is_separator_and_eq(',') {
38 iter.next_separator_eq_or_err('.')?;
39 iter.next_separator_eq_or_err('.')?;
40 iter.next_separator_eq_or_err('.')?;
41 true
42 } else {
43 false
44 };
45 iter.next_separator_eq_or_err(')')?;
46 let start = start
47 .text()
48 .filter(|txt| !txt.eq_ignore_ascii_case("MIN"))
49 .map(|t| match t.parse::<i64>() {
50 Ok(lit) => LitOrRef::Lit(lit),
51 Err(_) => LitOrRef::Ref(t.to_string()),
52 });
53
54 let end = end
55 .text()
56 .filter(|txt| !txt.eq_ignore_ascii_case("MAX"))
57 .map(|t| match t.parse::<i64>() {
58 Ok(lit) => LitOrRef::Lit(lit),
59 Err(_) => LitOrRef::Ref(t.to_string()),
60 });
61
62 match (start, end) {
63 (Some(LitOrRef::Lit(0)), None) | (None, Some(LitOrRef::Lit(i64::MAX))) => {
64 Range(None, None, extensible)
65 }
66 (start, end) => Range(start, end, extensible),
67 }
68 } else {
69 Range(None, None, false)
70 };
71 Ok(Self { range, constants })
72 }
73}
74
75impl TryResolve<i64, Integer<i64>> for Integer<LitOrRef<i64>> {
76 fn try_resolve(&self, resolver: &impl Resolver<i64>) -> Result<Integer<i64>, ResolveError> {
77 Ok(Integer {
78 range: Range(
79 self.range
80 .0
81 .as_ref()
82 .map(|lor| resolver.resolve(lor))
83 .transpose()?,
84 self.range
85 .1
86 .as_ref()
87 .map(|lor| resolver.resolve(lor))
88 .transpose()?,
89 self.range.2,
90 ),
91 constants: self.constants.clone(),
93 })
94 }
95}