rasn/
oer.rs

1//! Codec for Octet Encoding Rules (OER).
2//! Encodes in canonical format (COER), and decodes in more versatile format (OER).
3pub mod de;
4pub mod enc;
5mod ranges;
6
7pub use self::{de::Decoder, enc::Encoder};
8use crate::error::{DecodeError, EncodeError};
9use crate::types::Constraints;
10/// Attempts to decode `T` from `input` using OER.
11///
12/// # Errors
13/// Returns `DecodeError` if `input` is not valid OER encoding specific to the expected type.
14pub fn decode<T: crate::Decode>(input: &[u8]) -> Result<T, DecodeError> {
15    T::decode(&mut Decoder::new(
16        crate::types::BitStr::from_slice(input),
17        de::DecoderOptions::oer(),
18    ))
19}
20/// Attempts to encode `value` of type `T` to OER.
21///
22/// # Errors
23/// Returns `EncodeError` if `value` cannot be encoded as COER, usually meaning that constraints
24/// are not met.
25pub fn encode<T: crate::Encode>(value: &T) -> Result<alloc::vec::Vec<u8>, EncodeError> {
26    let mut enc = Encoder::new(enc::EncoderOptions::coer());
27    value.encode(&mut enc)?;
28    Ok(enc.output())
29}
30/// Attempts to decode `T` from `input` using OER with constraints.
31///
32/// # Errors
33/// Returns `DecodeError` if `input` is not valid OER encoding, while setting specific constraints.
34#[allow(dead_code)]
35pub fn decode_with_constraints<T: crate::Decode>(
36    constraints: Constraints,
37    input: &[u8],
38) -> Result<T, DecodeError> {
39    T::decode_with_constraints(
40        &mut Decoder::new(
41            crate::types::BitStr::from_slice(input),
42            de::DecoderOptions::oer(),
43        ),
44        constraints,
45    )
46}
47/// Attempts to encode `value` to COER with constraints.
48///
49/// # Errors
50/// Returns `EncodeError` if `value` cannot be encoded as COER, while setting specific constraints.
51#[allow(dead_code)]
52pub fn encode_with_constraints<T: crate::Encode>(
53    constraints: Constraints,
54    value: &T,
55) -> Result<alloc::vec::Vec<u8>, EncodeError> {
56    let mut enc = Encoder::new(enc::EncoderOptions::coer());
57    value.encode_with_constraints(&mut enc, constraints)?;
58    Ok(enc.output())
59}
60
61#[cfg(test)]
62mod tests {
63    // Test differences of OER and COER.
64    // On some cases, COER is more stricter than OER.
65    use crate as rasn;
66    use crate::prelude::*;
67
68    #[test]
69    fn test_bool() {
70        for value in 0x01..=0xFEu8 {
71            let bytes = [value];
72            // Coer fails for other values than 0x00 and 0xFF.
73            decode_error!(coer, bool, &bytes);
74            decode_ok!(oer, bool, &bytes, true);
75        }
76    }
77    #[test]
78    fn test_length_determinant() {
79        // short with leading zeros
80        decode_error!(coer, Integer, &[0x00, 0x00, 0x00, 0x01, 0x01]);
81        decode_ok!(oer, Integer, &[0x00, 0x00, 0x00, 0x01, 0x01], 1.into());
82        decode_error!(coer, Integer, &[0x00, 0x00, 0x00, 0x01, 0x01]);
83        // Long form when not needed
84        decode_error!(coer, Integer, &[0b1000_0001, 0x01, 0x01]);
85        decode_ok!(oer, Integer, &[0b1000_0001, 0x01, 0x01], 1.into());
86    }
87    #[test]
88    fn test_enumerated() {
89        // short with leading zeros
90        #[derive(AsnType, Decode, Encode, Debug, Clone, Copy, PartialEq)]
91        #[rasn(enumerated)]
92        enum Test {
93            A = 1,
94            B = 2,
95        }
96        #[derive(AsnType, Decode, Encode, Debug, Clone, Copy, PartialEq)]
97        #[rasn(enumerated)]
98        enum TestDefaults {
99            A,
100            B,
101        }
102        // Leading zeroes
103        decode_error!(coer, Test, &[0x00, 0x00, 0x00, 0x01, 0x01]);
104        // Leading zeros not allowed for enumerated values in any case
105        round_trip!(oer, Test, Test::A, &[0x01]);
106        round_trip!(oer, TestDefaults, TestDefaults::A, &[0x00]);
107        // Unfortunately, below is correct since we just parse the first byte and do not chek the
108        // remainder in reality
109        decode_ok!(oer, TestDefaults, &[0x00, 0x00], TestDefaults::A);
110        decode_error!(oer, Test, &[0x00, 0x01]);
111        decode_error!(oer, Test, &[0x00, 0x81, 0x01]);
112        decode_ok!(oer, Test, &[0x81, 0x01], Test::A);
113        decode_ok!(oer, Test, &[0x01], Test::A);
114        // Long form when not needed
115        decode_error!(coer, Test, &[0b1000_0001, 0x01]);
116        decode_ok!(oer, Test, &[0b1000_0001, 0x01], Test::A);
117    }
118}