1use crate::types::Constraints;
7
8pub use super::per::*;
9
10pub fn decode<T: crate::Decode>(input: &[u8]) -> Result<T, crate::error::DecodeError> {
12 crate::per::decode(de::DecoderOptions::aligned(), input)
13}
14
15pub fn encode<T: crate::Encode>(
17 value: &T,
18) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
19 crate::per::encode(enc::EncoderOptions::aligned(), value)
20}
21
22pub fn decode_with_constraints<T: crate::Decode>(
24 constraints: Constraints,
25 input: &[u8],
26) -> Result<T, crate::error::DecodeError> {
27 crate::per::decode_with_constraints(de::DecoderOptions::aligned(), constraints, input)
28}
29
30pub fn encode_with_constraints<T: crate::Encode>(
32 constraints: Constraints,
33 value: &T,
34) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
35 crate::per::encode_with_constraints(enc::EncoderOptions::aligned(), constraints, value)
36}
37
38#[cfg(test)]
39mod tests {
40 use crate::{
41 prelude::*,
42 types::{constraints::*, *},
43 };
44
45 #[test]
46 fn bitstring() {
47 use bitvec::prelude::*;
48 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
52 #[rasn(crate_root = "crate")]
53 struct D {
54 a: bool,
55 b: BitString,
56 }
57
58 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
59 #[rasn(crate_root = "crate")]
60 struct E {
61 a: bool,
62 #[rasn(size(1))]
63 b: BitString,
64 #[rasn(size(16))]
65 c: BitString,
66 }
67
68 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
69 #[rasn(crate_root = "crate")]
70 struct G {
71 a: BitString,
72 b: bool,
73 }
74
75 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
82 #[rasn(crate_root = "crate")]
83 struct M {
84 a: bool,
85 #[rasn(size("1..=160", extensible))]
86 b: BitString,
87 }
88
89 round_trip!(
93 aper,
94 BitString,
95 bitvec::bitvec![u8, Msb0; 0, 1, 0, 0],
96 &[0x04, 0x40]
97 );
98 round_trip!(
109 aper,
110 BitString,
111 BitString::from_vec([0x55; 2048].into()),
112 &*{
113 let mut bytes = vec![0xc1];
114 bytes.extend([0x55; 2048]);
115 bytes.push(0x00);
116 bytes
117 }
118 );
119 }
137
138 #[test]
139 fn integer() {
140 type B = ConstrainedInteger<5, 99>;
141
142 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
143 #[rasn(crate_root = "crate")]
144 struct C {
145 a: bool,
146 b: Integer,
147 c: bool,
148 #[rasn(value("-10..=400"))]
149 d: Integer,
150 }
151
152 type D = ConstrainedInteger<0, 254>;
153 type E = ConstrainedInteger<0, 255>;
154 type F = ConstrainedInteger<0, 256>;
155 type G = ConstrainedInteger<0, 65535>;
156 type H = ConstrainedInteger<0, 65536>;
157 type I = ConstrainedInteger<0, 10000000000>;
158
159 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
160 #[rasn(crate_root = "crate")]
161 struct J {
162 a: bool,
163 #[rasn(value("0..=254"))]
164 b: Integer,
165 #[rasn(value("0..=255"))]
166 c: Integer,
167 d: bool,
168 #[rasn(value("0..=256"))]
169 e: Integer,
170 }
171
172 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
173 #[rasn(crate_root = "crate")]
174 struct L {
175 #[rasn(value("7..=7"))]
176 a: Integer,
177 }
178
179 type N = ConstrainedInteger<0, 65535>;
180 type O = ConstrainedInteger<0, 65536>;
181 type P = ConstrainedInteger<0, 2147483647>;
182 type Q = ConstrainedInteger<0, 4294967295>;
183 type R = ConstrainedInteger<0, 4294967296>;
184
185 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
186 #[rasn(crate_root = "crate")]
187 struct S {
188 a: bool,
189 #[rasn(value("-10000..=704000000000000001"))]
190 b: Integer,
191 c: bool,
192 }
193
194 round_trip!(aper, Integer, 32768.into(), &[0x03, 0x00, 0x80, 0x00]);
195 round_trip!(aper, Integer, 32767.into(), &[0x02, 0x7f, 0xff]);
196 round_trip!(aper, Integer, 256.into(), &[0x02, 0x01, 0x00]);
197 round_trip!(aper, Integer, 255.into(), &[0x02, 0x00, 0xff]);
198 round_trip!(aper, Integer, 128.into(), &[0x02, 0x00, 0x80]);
199 round_trip!(aper, Integer, 127.into(), &[0x01, 0x7f]);
200 round_trip!(aper, Integer, 1.into(), &[0x01, 0x01]);
201 round_trip!(aper, Integer, 0.into(), &[0x01, 0x00]);
202 round_trip!(aper, Integer, (-1).into(), &[0x01, 0xff]);
203 round_trip!(aper, Integer, (-128).into(), &[0x01, 0x80]);
204 round_trip!(aper, Integer, (-129).into(), &[0x02, 0xff, 0x7f]);
205 round_trip!(aper, Integer, (-256).into(), &[0x02, 0xff, 0x00]);
206 round_trip!(aper, Integer, (-32768).into(), &[0x02, 0x80, 0x00]);
207 round_trip!(aper, Integer, (-32769).into(), &[0x03, 0xff, 0x7f, 0xff]);
208 round_trip!(aper, B, 5.into(), &[0x00]);
209 round_trip!(aper, B, 6.into(), &[0x02]);
210 round_trip!(aper, B, 99.into(), &[0xbc]);
211 round_trip!(
212 aper,
213 C,
214 C {
215 a: true,
216 b: Integer::from(43554344223i64),
217 c: false,
218 d: Integer::from(-9)
219 },
220 &[0x80, 0x05, 0x0a, 0x24, 0x0a, 0x8d, 0x1f, 0x00, 0x00, 0x01]
221 );
222 round_trip!(aper, D, 253.into(), &[0xfd]);
223 round_trip!(aper, E, 253.into(), &[0xfd]);
224 round_trip!(aper, F, 253.into(), &[0x00, 0xfd]);
225 round_trip!(aper, G, 253.into(), &[0x00, 0xfd]);
226 round_trip!(aper, H, 253.into(), &[0x00, 0xfd]);
227 round_trip!(aper, H, 256.into(), &[0x40, 0x01, 0x00]);
228 round_trip!(aper, H, 65536.into(), &[0x80, 0x01, 0x00, 0x00]);
229 round_trip!(aper, I, 0.into(), &[0x00, 0x00]);
230 round_trip!(aper, I, 1.into(), &[0x00, 0x01]);
231 round_trip!(
232 aper,
233 I,
234 10000000000i64.into(),
235 &[0x80, 0x02, 0x54, 0x0b, 0xe4, 0x00]
236 );
237 round_trip!(
238 aper,
239 J,
240 J {
241 a: false,
242 b: 253.into(),
243 c: 253.into(),
244 d: false,
245 e: 253.into()
246 },
247 &[0x7e, 0x80, 0xfd, 0x00, 0x00, 0xfd]
248 );
249 round_trip!(aper, L, L { a: 7.into() }, &[]);
250 round_trip!(aper, N, 1.into(), &[0x00, 0x01]);
252 round_trip!(aper, N, 255.into(), &[0x00, 0xff]);
253 round_trip!(aper, N, 256.into(), &[0x01, 0x00]);
254 round_trip!(aper, N, 65535.into(), &[0xff, 0xff]);
255 round_trip!(aper, O, 1.into(), &[0x00, 0x01]);
256 round_trip!(aper, O, 255.into(), &[0x00, 0xff]);
257 round_trip!(aper, O, 256.into(), &[0x40, 0x01, 0x00]);
258 round_trip!(aper, O, 65535.into(), &[0x40, 0xff, 0xff]);
259 round_trip!(aper, O, 65536.into(), &[0x80, 0x01, 0x00, 0x00]);
260 round_trip!(aper, P, 1.into(), &[0x00, 0x01]);
261 round_trip!(aper, P, 255.into(), &[0x00, 0xff]);
262 round_trip!(aper, P, 256.into(), &[0x40, 0x01, 0x00]);
263 round_trip!(aper, P, 65535.into(), &[0x40, 0xff, 0xff]);
264 round_trip!(aper, P, 65536.into(), &[0x80, 0x01, 0x00, 0x00]);
265 round_trip!(aper, P, 16777215.into(), &[0x80, 0xff, 0xff, 0xff]);
266 round_trip!(aper, P, 16777216.into(), &[0xc0, 0x01, 0x00, 0x00, 0x00]);
267 round_trip!(aper, P, 100000000.into(), &[0xc0, 0x05, 0xf5, 0xe1, 0x00]);
268 round_trip!(
269 aper,
270 Q,
271 4294967295u64.into(),
272 &[0xc0, 0xff, 0xff, 0xff, 0xff]
273 );
274 round_trip!(
275 aper,
276 R,
277 4294967296u64.into(),
278 &[0x80, 0x01, 0x00, 0x00, 0x00, 0x00]
279 );
280 round_trip!(
281 aper,
282 S,
283 S {
284 a: true,
285 b: 0.into(),
286 c: true
287 },
288 &[0x90, 0x27, 0x10, 0x80]
289 );
290 }
291
292 #[test]
293 fn visible_string() {
294 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
307 #[rasn(crate_root = "crate")]
308 struct D {
309 a: bool,
310 #[rasn(size(1))]
311 b: VisibleString,
312 }
313
314 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
315 #[rasn(crate_root = "crate")]
316 struct E {
317 a: bool,
318 #[rasn(size(2))]
319 b: VisibleString,
320 }
321
322 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
323 #[rasn(crate_root = "crate")]
324 struct F {
325 a: bool,
326 #[rasn(size(3))]
327 b: VisibleString,
328 }
329
330 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
331 #[rasn(crate_root = "crate")]
332 struct G {
333 a: bool,
334 #[rasn(size("0..=1"))]
335 b: VisibleString,
336 }
337
338 #[derive(Debug, AsnType, Decode, Encode, PartialEq)]
339 #[rasn(crate_root = "crate")]
340 struct H {
341 a: bool,
342 #[rasn(size("0..=2"))]
343 b: VisibleString,
344 }
345 round_trip_with_constraints!(
388 aper,
389 VisibleString,
390 Constraints::new(&[
391 Constraint::PermittedAlphabet(
392 PermittedAlphabet::new(&[
393 b'a' as u32,
394 b'b' as u32,
395 b'c' as u32,
396 b'd' as u32,
397 b'e' as u32,
398 b'f' as u32,
399 b'g' as u32,
400 b'h' as u32,
401 b'i' as u32,
402 b'j' as u32,
403 b'k' as u32,
404 b'l' as u32,
405 b'm' as u32,
406 b'n' as u32,
407 b'o' as u32,
408 b'p' as u32,
409 b'q' as u32,
410 b'r' as u32,
411 b's' as u32,
412 b't' as u32,
413 b'u' as u32,
414 b'v' as u32,
415 b'w' as u32,
416 b'x' as u32,
417 b'y' as u32,
418 b'z' as u32,
419 ])
420 .into()
421 ),
422 Constraint::Size(Size::new(Bounded::new(1, 255)).into())
423 ]),
424 VisibleString::try_from("hej").unwrap(),
425 &[0x02, 0x68, 0x65, 0x6a]
426 );
427 round_trip_with_constraints!(
428 aper,
429 VisibleString,
430 Constraints::new(&[Constraint::PermittedAlphabet(
431 PermittedAlphabet::new(&[b'a' as u32,]).into()
432 ),]),
433 VisibleString::try_from("a").unwrap(),
434 &[0x01]
435 );
436 }
437
438 #[test]
439 fn issue_192() {
440 use crate as rasn;
442
443 use rasn::AsnType;
444
445 #[derive(rasn::AsnType, rasn::Encode, rasn::Decode, Debug, Clone, PartialEq, Eq)]
446 #[rasn(automatic_tags, option_type(Option))]
447 #[non_exhaustive]
448 pub struct Updates {
449 pub updates: Vec<u8>,
450 }
451
452 #[derive(rasn::AsnType, rasn::Encode, rasn::Decode, Debug, Clone, PartialEq, Eq)]
453 #[rasn(automatic_tags, option_type(Option))]
454 #[rasn(choice)]
455 #[non_exhaustive]
456 pub enum Message {
457 Updates(Updates),
458 }
459
460 let msg = Message::Updates(Updates { updates: vec![1] });
461
462 round_trip!(aper, Message, msg, &[0, 1, 1]);
463 }
464
465 #[test]
466 fn issue_201() {
467 use crate as rasn;
468 use crate::prelude::*;
469
470 const T124_IDENTIFIER_KEY: &Oid = Oid::const_new(&[0, 0, 20, 124, 0, 1]);
471 #[derive(Debug, AsnType, Encode, rasn::Decode)]
472 #[rasn(choice, automatic_tags)]
473 enum Key {
474 #[rasn(tag(explicit(5)))]
475 Object(ObjectIdentifier),
476 H221NonStandard(OctetString),
477 }
478
479 #[derive(Debug, AsnType, rasn::Encode, rasn::Decode)]
480 #[rasn(automatic_tags)]
481 struct ConnectData {
482 t124_identifier_key: Key,
483 connect_pdu: OctetString,
484 }
485
486 let connect_pdu: OctetString = vec![0u8, 1u8, 2u8, 3u8].into();
487 let connect_data = ConnectData {
488 t124_identifier_key: Key::Object(T124_IDENTIFIER_KEY.into()),
489 connect_pdu,
490 };
491
492 let encoded = rasn::aper::encode(&connect_data).expect("failed to encode");
493 let _: ConnectData = rasn::aper::decode(&encoded).expect("failed to decode");
494 }
495}