1use crate::types::integer::Asn1Int;
2use crate::error as asn1err;
3use crate::tag::Tag;
4use crate::traits::Asn1Object;
5use std::ops::{Deref, DerefMut};
6
7pub static ENUMERATED_TAG_NUMBER: u8 = 0x0a;
8
9#[derive(Clone, Debug, Default, PartialEq)]
10pub struct Enumerated<T: Asn1Int>(T);
11
12impl<T: Asn1Int> Enumerated<T> {
13 pub fn new(v: T) -> Self {
14 return Self(v);
15 }
16}
17
18impl<T: Asn1Int> Deref for Enumerated<T> {
19 type Target = T;
20 fn deref(&self) -> &Self::Target {
21 &self.0
22 }
23}
24
25impl<T: Asn1Int> DerefMut for Enumerated<T> {
26 fn deref_mut(&mut self) -> &mut Self::Target {
27 &mut self.0
28 }
29}
30
31impl<T: Asn1Int> Asn1Object for Enumerated<T> {
32 fn tag() -> Tag {
33 return Tag::new_primitive_universal(ENUMERATED_TAG_NUMBER);
34 }
35
36 fn build_value(&self) -> Vec<u8> {
37 return self.0.build_int_value();
38 }
39
40 fn parse_value(&mut self, raw: &[u8]) -> asn1err::Result<()> {
41 self.0 = T::parse_int_value(raw)?;
42 return Ok(());
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn test_build() {
52 assert_eq!(vec![0xa, 0x1, 0x0], Enumerated::new(0 as u32).build());
53 assert_eq!(vec![0xa, 0x1, 0x1], Enumerated::new(1 as u32).build());
54 assert_eq!(
55 vec![0xa, 0x1, 0xff],
56 Enumerated::new((-1i32) as u32).build()
57 );
58
59 assert_eq!(vec![0xa, 0x1, 0x7F], Enumerated::new(127 as u32).build());
60 assert_eq!(
61 vec![0xa, 0x2, 0x00, 0x80],
62 Enumerated::new(128 as u32).build()
63 );
64 assert_eq!(
65 vec![0xa, 0x2, 0x01, 0x00],
66 Enumerated::new(256 as u32).build()
67 );
68 assert_eq!(
69 vec![0xa, 0x1, 0x80],
70 Enumerated::new(-128i32 as u32).build()
71 );
72 assert_eq!(
73 vec![0xa, 0x2, 0xFF, 0x7F],
74 Enumerated::new(-129i32 as u32).build()
75 );
76
77 assert_eq!(
78 vec![0xa, 0x4, 0xF8, 0x45, 0x33, 0x8],
79 Enumerated::new(4165284616 as u32).build()
80 );
81 }
82
83 #[test]
84 fn test_parse() {
85 assert_eq!(
86 Enumerated::new(0 as u32),
87 Enumerated::<u32>::parse(&[0xa, 0x1, 0x0]).unwrap().1
88 );
89 assert_eq!(
90 Enumerated::new(1 as u32),
91 Enumerated::<u32>::parse(&[0xa, 0x1, 0x1]).unwrap().1
92 );
93 assert_eq!(
94 Enumerated::new(-1i32 as u32),
95 Enumerated::<u32>::parse(&[0xa, 0x1, 0xff]).unwrap().1
96 );
97
98 assert_eq!(
99 Enumerated::new(127 as u32),
100 Enumerated::<u32>::parse(&[0xa, 0x1, 0x7F]).unwrap().1
101 );
102 assert_eq!(
103 Enumerated::new(128u32),
104 Enumerated::<u32>::parse(&[0xa, 0x2, 0x00, 0x80]).unwrap().1
105 );
106 assert_eq!(
107 Enumerated::new(256u32),
108 Enumerated::<u32>::parse(&[0xa, 0x2, 0x01, 0x00]).unwrap().1
109 );
110 assert_eq!(
111 Enumerated::new(-128i32 as u32),
112 Enumerated::<u32>::parse(&[0xa, 0x1, 0x80]).unwrap().1
113 );
114 assert_eq!(
115 Enumerated::new(-129i32 as u32),
116 Enumerated::<u32>::parse(&[0xa, 0x2, 0xFF, 0x7F]).unwrap().1
117 );
118
119 assert_eq!(
120 Enumerated::new(4165284616u32),
121 Enumerated::<u32>::parse(&[0xa, 0x4, 0xF8, 0x45, 0x33, 0x8])
122 .unwrap()
123 .1
124 );
125 }
126
127 #[test]
128 fn test_parse_with_excesive_bytes() {
129 let x: &[u8] = &[0x22];
130 assert_eq!(
131 (x, Enumerated::new(0)),
132 Enumerated::<u32>::parse(&[0xa, 0x1, 0x0, 0x22]).unwrap()
133 );
134 assert_eq!(
135 (x, Enumerated::new(1)),
136 Enumerated::<u32>::parse(&[0xa, 0x1, 0x1, 0x22]).unwrap()
137 );
138 assert_eq!(
139 (x, Enumerated::new(-1i32 as u32)),
140 Enumerated::<u32>::parse(&[0xa, 0x1, 0xff, 0x22]).unwrap()
141 );
142
143 assert_eq!(
144 (x, Enumerated::new(127)),
145 Enumerated::<u32>::parse(&[0xa, 0x1, 0x7F, 0x22]).unwrap()
146 );
147 assert_eq!(
148 (x, Enumerated::new(128)),
149 Enumerated::<u32>::parse(&[0xa, 0x2, 0x00, 0x80, 0x22]).unwrap()
150 );
151 assert_eq!(
152 (x, Enumerated::new(256u32)),
153 Enumerated::<u32>::parse(&[0xa, 0x2, 0x01, 0x00, 0x22]).unwrap()
154 );
155 assert_eq!(
156 (x, Enumerated::new(-128i32 as u32)),
157 Enumerated::<u32>::parse(&[0xa, 0x1, 0x80, 0x22]).unwrap()
158 );
159 assert_eq!(
160 (x, Enumerated::new(-129i32 as u32)),
161 Enumerated::<u32>::parse(&[0xa, 0x2, 0xFF, 0x7F, 0x22]).unwrap()
162 );
163
164 assert_eq!(
165 (x, Enumerated::new(4165284616u32)),
166 Enumerated::<u32>::parse(&[0xa, 0x4, 0xF8, 0x45, 0x33, 0x8, 0x22])
167 .unwrap()
168 );
169 }
170
171 #[should_panic(expected = "UnmatchedTag")]
172 #[test]
173 fn test_parse_with_invalid_tag() {
174 Enumerated::<u32>::parse(&[0x7, 0x1, 0x0]).unwrap();
175 }
176
177 #[should_panic(expected = "IncorrectValue(\"No octets for i32\")")]
178 #[test]
179 fn test_parse_without_enough_value_octets() {
180 Enumerated::<u32>::parse(&[0xa, 0x0]).unwrap();
181 }
182
183 #[should_panic(
184 expected = "IncorrectValue(\"Too many octets for i32: 9 octets\")"
185 )]
186 #[test]
187 fn test_parse_with_too_much_value_octets() {
188 Enumerated::<u32>::parse(&[
189 0xa, 9, 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
190 ])
191 .unwrap();
192 }
193
194 #[test]
195 fn test_parse_with_the_limit_of_value_octets() {
196 Enumerated::<u32>::parse(&[0xa, 4, 0, 0x1, 0x2, 0x3]).unwrap();
197 }
198}