Skip to main content

rasn/
ber.rs

1//! # Basic Encoding Rules
2
3pub mod de;
4pub mod enc;
5mod identifier;
6mod rules;
7
8pub use identifier::Identifier;
9pub(crate) use rules::EncodingRules;
10
11/// Attempts to decode `T` from `input` using BER.
12/// # Errors
13/// Returns error specific to BER decoder if decoding is not possible.
14pub fn decode<T: crate::Decode>(input: &[u8]) -> Result<T, crate::error::DecodeError> {
15    T::decode(&mut de::Decoder::new(input, de::DecoderOptions::ber()))
16}
17
18/// Attempts to decode `T` from `input` using BER. Returns both `T` and reference to the remainder of the input.
19///
20/// # Errors
21/// Returns `DecodeError` if `input` is not valid BER encoding specific to the expected type.
22pub fn decode_with_remainder<T: crate::Decode>(
23    input: &[u8],
24) -> Result<(T, &[u8]), crate::error::DecodeError> {
25    let decoder = &mut de::Decoder::new(input, de::DecoderOptions::ber());
26    let decoded_instance = T::decode(decoder)?;
27    Ok((decoded_instance, decoder.remaining()))
28}
29
30/// Attempts to encode `value` to BER.
31/// # Errors
32/// Returns error specific to BER encoder if encoding is not possible.
33pub fn encode<T: crate::Encode>(
34    value: &T,
35) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
36    let mut enc = enc::Encoder::new(enc::EncoderOptions::ber());
37
38    value.encode(&mut enc)?;
39
40    Ok(enc.output())
41}
42
43/// Creates a new BER encoder that can be used to encode any value.
44/// # Errors
45/// Returns error specific to BER encoder if encoding is not possible.
46pub fn encode_scope(
47    encode_fn: impl FnOnce(&mut crate::ber::enc::Encoder) -> Result<(), crate::error::EncodeError>,
48) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
49    let mut enc = crate::ber::enc::Encoder::new(crate::ber::enc::EncoderOptions::ber());
50
51    (encode_fn)(&mut enc)?;
52
53    Ok(enc.output())
54}
55
56#[cfg(test)]
57mod tests {
58    use crate::error::DecodeErrorKind;
59    use alloc::borrow::{Cow, ToOwned};
60    use alloc::vec;
61    use alloc::vec::Vec;
62    use bitvec::order::Msb0;
63    use chrono::{DateTime, FixedOffset, NaiveDate, Utc};
64
65    use crate::{
66        ber::{decode, encode},
67        types::*,
68    };
69
70    #[derive(Clone, Copy, Hash, Debug, PartialEq)]
71    struct C0;
72    impl AsnType for C0 {
73        const TAG: Tag = Tag::new(Class::Context, 0);
74    }
75
76    #[test]
77    fn oversized_integer() {
78        const DATA: &[u8] = &[0x02, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
79
80        assert!(matches!(
81            &*decode::<u32>(DATA).unwrap_err().kind,
82            DecodeErrorKind::IntegerOverflow { max_width: 32 }
83        ));
84
85        assert!(matches!(
86            &*decode::<i32>(DATA).unwrap_err().kind,
87            DecodeErrorKind::IntegerOverflow { max_width: 32 }
88        ));
89    }
90
91    #[test]
92    fn leading_integer_bytes() {
93        const DATA: &[u8] = &[0x02, 0x06, 0x00, 0x00, 0x33, 0x44, 0x55, 0x66];
94        assert_eq!(decode::<u32>(DATA).unwrap(), 0x3344_5566_u32);
95
96        const SIGNED_DATA: &[u8] = &[0x02, 0x06, 0xFF, 0xFF, 0x83, 0x44, 0x55, 0x66];
97        assert_eq!(decode::<i32>(SIGNED_DATA).unwrap(), -2_092_673_690);
98    }
99
100    #[test]
101    fn bit_string() {
102        const DATA: &[u8] = &[0, 0xD0];
103        let small = BitString::from_vec(DATA.to_owned());
104        let bits = BitString::from_vec([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..].to_owned());
105        let padding_test = BitString::from_element(0x42);
106        let padding_expected: &[u8] = &[0x03, 0x02, 0x00, 0x42];
107        let trailing_test = bitvec::bitvec![u8, Msb0; 1, 0, 0, 0, 0, 1, 1, 0];
108        let trailing_expected: &[u8] = &[0x03, 0x02, 0x00, 0x86];
109
110        assert_eq!(
111            small,
112            decode::<BitString>(&encode(&small).unwrap()).unwrap()
113        );
114        assert_eq!(bits, decode::<BitString>(&encode(&bits).unwrap()).unwrap());
115        assert_eq!(padding_expected, encode(&padding_test).unwrap());
116        assert_eq!(trailing_expected, encode(&trailing_test).unwrap());
117    }
118
119    #[test]
120    fn implicit_prefix() {
121        type MyInteger = Implicit<C0, u64>;
122
123        let new_int = MyInteger::new(5);
124
125        assert_eq!(new_int, decode(&encode(&new_int).unwrap()).unwrap());
126    }
127
128    #[test]
129    fn explicit_prefix() {
130        type MyInteger = Explicit<C0, u64>;
131
132        let new_int = MyInteger::new(5);
133        let data = &[0xA0, 3, 0x2, 0x1, 5][..];
134
135        assert_eq!(data, &encode(&new_int).unwrap());
136        assert_eq!(new_int, decode(&encode(&new_int).unwrap()).unwrap());
137    }
138
139    #[test]
140    fn implicit_tagged_constructed() {
141        type ImpVec = Implicit<C0, Vec<i32>>;
142
143        let value = ImpVec::new(vec![1, 2]);
144        let data = &[0xA0, 6, 2, 1, 1, 2, 1, 2][..];
145
146        assert_eq!(data, &*crate::ber::encode(&value).unwrap());
147        assert_eq!(value, crate::ber::decode::<ImpVec>(data).unwrap());
148    }
149
150    #[test]
151    fn explicit_empty_tag() {
152        use crate as rasn;
153        use rasn::prelude::*;
154        #[derive(Debug, AsnType, Encode, Decode, PartialEq)]
155        struct EmptyTag {
156            #[rasn(tag(explicit(0)))]
157            a: Option<()>,
158        }
159
160        let value = EmptyTag { a: None };
161        // Absent field - only sequence tag present with length of 0
162        let data = &[0x30, 0][..];
163
164        assert_eq!(data, &*crate::ber::encode(&value).unwrap());
165        assert_eq!(value, crate::ber::decode::<EmptyTag>(data).unwrap());
166    }
167
168    #[test]
169    #[allow(clippy::items_after_statements)]
170    fn set() {
171        #[derive(Debug, PartialEq)]
172        struct Set {
173            age: u32,
174            name: Utf8String,
175        }
176
177        impl AsnType for Set {
178            const TAG: Tag = Tag::SET;
179        }
180
181        impl crate::types::Constructed<2, 0> for Set {
182            const FIELDS: crate::types::fields::Fields<2> =
183                crate::types::fields::Fields::from_static([
184                    crate::types::fields::Field::new_required(0, u32::TAG, u32::TAG_TREE, "age"),
185                    crate::types::fields::Field::new_required(
186                        1,
187                        Utf8String::TAG,
188                        Utf8String::TAG_TREE,
189                        "name",
190                    ),
191                ]);
192        }
193
194        let example = Set {
195            age: 1,
196            name: "Jane".into(),
197        };
198        let age_then_name = [0x31, 0x9, 0x2, 0x1, 0x1, 0xC, 0x4, 0x4a, 0x61, 0x6e, 0x65];
199        let name_then_age = [0x31, 0x9, 0xC, 0x4, 0x4a, 0x61, 0x6e, 0x65, 0x2, 0x1, 0x1];
200
201        assert_eq!(&age_then_name[..], crate::ber::encode(&example).unwrap());
202
203        assert_eq!(
204            crate::ber::decode::<Set>(&age_then_name).unwrap(),
205            crate::ber::decode::<Set>(&name_then_age).unwrap()
206        );
207
208        impl crate::Decode for Set {
209            fn decode_with_tag_and_constraints<D: crate::Decoder>(
210                decoder: &mut D,
211                tag: Tag,
212                _: Constraints,
213            ) -> Result<Self, D::Error> {
214                use crate::de::Error;
215
216                #[derive(crate::AsnType, crate::Decode)]
217                #[rasn(crate_root = "crate")]
218                #[rasn(choice)]
219                pub enum Fields {
220                    Age(u32),
221                    Name(Utf8String),
222                }
223                let codec = decoder.codec();
224                decoder.decode_set::<2, 0, Fields, _, _, _>(
225                    tag,
226                    |decoder, indice, tag| match (indice, tag) {
227                        (0, u32::TAG) => <_>::decode(decoder).map(Fields::Age),
228                        (1, Utf8String::TAG) => <_>::decode(decoder).map(Fields::Name),
229                        (_, _) => Err(D::Error::custom("unknown field", codec)),
230                    },
231                    |fields| {
232                        let mut age = None;
233                        let mut name = None;
234
235                        for field in fields {
236                            match field {
237                                Fields::Age(value) => age = value.into(),
238                                Fields::Name(value) => name = value.into(),
239                            }
240                        }
241
242                        Ok(Self {
243                            age: age.ok_or_else(|| D::Error::missing_field("age", codec))?,
244                            name: name.ok_or_else(|| D::Error::missing_field("name", codec))?,
245                        })
246                    },
247                )
248            }
249        }
250
251        impl crate::Encode for Set {
252            fn encode_with_tag_and_constraints<'b, EN: crate::Encoder<'b>>(
253                &self,
254                encoder: &mut EN,
255                tag: crate::types::Tag,
256                _: Constraints,
257                _: crate::types::Identifier,
258            ) -> Result<(), EN::Error> {
259                encoder.encode_set::<2, 0, Self, _>(
260                    tag,
261                    |encoder| {
262                        self.age.encode(encoder)?;
263                        self.name.encode(encoder)?;
264                        Ok(())
265                    },
266                    crate::types::Identifier::EMPTY,
267                )?;
268
269                Ok(())
270            }
271        }
272    }
273    #[test]
274    fn test_generalized_time() {
275        // "20801009130005.342Z"
276        let offset = chrono::FixedOffset::east_opt(0).unwrap();
277        let dt = NaiveDate::from_ymd_opt(2080, 10, 9)
278            .unwrap()
279            .and_hms_micro_opt(13, 0, 5, 342_000)
280            .unwrap()
281            .and_local_timezone(offset);
282        round_trip!(
283            ber,
284            GeneralizedTime,
285            GeneralizedTime::from(dt.unwrap(),),
286            &[
287                0x18, 0x13, 0x32, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x39, 0x31, 0x33, 0x30, 0x30,
288                0x30, 0x35, 0x2e, 0x33, 0x34, 0x32, 0x5a
289            ]
290        );
291
292        // https://github.com/XAMPPRocky/rasn/issues/57
293        let data = [
294            24, 19, 43, 53, 49, 54, 49, 53, 32, 32, 48, 53, 50, 52, 48, 57, 52, 48, 50, 48, 90,
295        ];
296        assert!(crate::der::decode::<crate::types::Open>(&data).is_err());
297        assert!(crate::ber::decode::<crate::types::Open>(&data).is_err());
298
299        // "20180122132900Z"
300        round_trip!(
301            ber,
302            GeneralizedTime,
303            GeneralizedTime::from(
304                NaiveDate::from_ymd_opt(2018, 1, 22)
305                    .unwrap()
306                    .and_hms_opt(13, 29, 0)
307                    .unwrap()
308                    .and_utc()
309            ),
310            &[
311                0x18, 0x0f, 0x32, 0x30, 0x31, 0x38, 0x30, 0x31, 0x32, 0x32, 0x31, 0x33, 0x32, 0x39,
312                0x30, 0x30, 0x5a
313            ]
314        );
315        // "20180122130000Z"
316        round_trip!(
317            ber,
318            GeneralizedTime,
319            GeneralizedTime::from(
320                NaiveDate::from_ymd_opt(2018, 1, 22)
321                    .unwrap()
322                    .and_hms_opt(13, 0, 0)
323                    .unwrap()
324                    .and_utc()
325            ),
326            &[
327                0x18, 0x0f, 0x32, 0x30, 0x31, 0x38, 0x30, 0x31, 0x32, 0x32, 0x31, 0x33, 0x30, 0x30,
328                0x30, 0x30, 0x5a
329            ]
330        );
331
332        // "20230122130000-0500" - converts to canonical form "20230122180000Z"
333        let offset = FixedOffset::east_opt(-3600 * 5).unwrap();
334        let dt1: DateTime<FixedOffset> = GeneralizedTime::from(DateTime::<Utc>::from(
335            NaiveDate::from_ymd_opt(2023, 1, 22)
336                .unwrap()
337                .and_hms_opt(13, 0, 0)
338                .unwrap()
339                .and_local_timezone(offset)
340                .unwrap(),
341        ));
342        round_trip!(
343            ber,
344            GeneralizedTime,
345            dt1,
346            &[
347                0x18, 0x0f, 0x32, 0x30, 0x32, 0x33, 0x30, 0x31, 0x32, 0x32, 0x31, 0x38, 0x30, 0x30,
348                0x30, 0x30, 0x5a
349            ]
350        );
351        // "20230122130000-0500" as bytes
352        let data = [
353            24, 19, 50, 48, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 48, 53, 48, 48,
354        ];
355        let result = crate::ber::decode::<crate::types::GeneralizedTime>(&data);
356        assert!(result.is_ok());
357        assert_eq!(dt1, result.unwrap());
358        // Above without timezone
359        let data = [
360            24, 14, 50, 48, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48,
361        ];
362        let result = crate::ber::decode::<crate::types::GeneralizedTime>(&data);
363        // if err, print error
364        if result.is_err() {
365            println!("{result:?}");
366        }
367        assert!(result.is_ok());
368        let data = [
369            24, 22, 50, 48, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 45, 0xE2, 0x82,
370            0xAC, 45, 45, 45,
371        ];
372        let result = crate::ber::decode::<crate::types::GeneralizedTime>(&data);
373        assert!(result.is_err());
374    }
375    #[test]
376    fn test_utc_time() {
377        // "180122132900Z"
378        round_trip!(
379            ber,
380            UtcTime,
381            UtcTime::from(
382                NaiveDate::from_ymd_opt(2018, 1, 22)
383                    .unwrap()
384                    .and_hms_opt(13, 29, 0)
385                    .unwrap()
386                    .and_utc()
387            ),
388            &[
389                0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x32, 0x31, 0x33, 0x32, 0x39, 0x30, 0x30,
390                0x5a
391            ]
392        );
393        // "230122130000-0500" - converts to canonical form "230122180000Z"
394        let offset = FixedOffset::east_opt(-3600 * 5).unwrap();
395        let dt1 = DateTime::<FixedOffset>::from_naive_utc_and_offset(
396            NaiveDate::from_ymd_opt(2023, 1, 22)
397                .unwrap()
398                .and_hms_opt(18, 0, 0)
399                .unwrap(),
400            offset,
401        );
402        round_trip!(
403            ber,
404            UtcTime,
405            dt1.into(),
406            &[
407                0x17, 0x0d, 0x32, 0x33, 0x30, 0x31, 0x32, 0x32, 0x31, 0x38, 0x30, 0x30, 0x30, 0x30,
408                0x5a
409            ]
410        );
411        // "230122130000-0500" as bytes
412        let data = [
413            23, 17, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 48, 53, 48, 48,
414        ];
415        let result = crate::ber::decode::<crate::types::UtcTime>(&data);
416        assert!(result.is_ok());
417        assert_eq!(dt1, result.unwrap());
418    }
419
420    #[test]
421    fn test_date() {
422        round_trip!(
423            ber,
424            Date,
425            NaiveDate::from_ymd_opt(2012, 12, 21).unwrap(),
426            &[
427                0x1f, 0x1f, 0x08, 0x32, 0x30, 0x31, 0x32, 0x31, 0x32, 0x32, 0x31
428            ]
429        );
430    }
431    #[test]
432    fn test_extended_sequence() {
433        use crate as rasn;
434        use rasn::prelude::*;
435        #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
436        #[rasn(automatic_tags)]
437        #[non_exhaustive]
438        pub struct ExtendedInteger {
439            #[rasn(extension_addition)]
440            pub extension: Option<u64>,
441        }
442        round_trip!(
443            ber,
444            ExtendedInteger,
445            ExtendedInteger {
446                extension: Some(42)
447            },
448            &[0x30, 0x03, 0x80, 0x01, 0x2A]
449        );
450        #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
451        #[non_exhaustive]
452        pub struct ExtendedExplicitInteger {
453            #[rasn(extension_addition)]
454            #[rasn(tag(explicit(5)))]
455            pub extension: u64,
456        }
457
458        round_trip!(
459            ber,
460            ExtendedExplicitInteger,
461            ExtendedExplicitInteger { extension: 42 },
462            &[0x30, 0x05, 0xA5, 0x03, 0x02, 0x01, 0x2A]
463        );
464    }
465    #[test]
466    fn test_optional_any() {
467        // https://github.com/librasn/rasn/issues/488
468        use crate as rasn;
469        use rasn::prelude::*;
470
471        #[derive(Debug, AsnType, Decode, Encode, PartialEq, Eq)]
472        struct IncomingRequest {
473            #[rasn(tag(Context, 0))]
474            handshake: Option<Any>,
475            #[rasn(tag(Context, 1))]
476            user_data: Option<Any>,
477        }
478        let incoming: IncomingRequest = rasn::Codec::Ber
479            .decode_from_binary(&[0x30, 0x06, 0xA1, 0x04, 0x01, 0x02, 0x03, 0x04])
480            .unwrap();
481        let expected = IncomingRequest {
482            handshake: None,
483            user_data: Some(Any::new(vec![0x01, 0x02, 0x03, 0x04])),
484        };
485        assert_eq!(incoming, expected)
486    }
487
488    #[test]
489    fn test_optional_variants() {
490        use crate as rasn;
491        use rasn::prelude::*;
492
493        #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
494        #[rasn(automatic_tags)]
495        #[rasn(choice)]
496        pub enum TestChoice {
497            Integer(i32),
498            Boolean(bool),
499        }
500
501        #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
502        #[rasn(automatic_tags)]
503        pub struct TestSequence {
504            a: Option<u32>,
505            b: Option<TestChoice>,
506            c: Option<Any>,
507            d: bool, // A required field to ensure sequence isn't empty
508        }
509
510        // Case 1: All optional fields are absent.
511        let value1 = TestSequence {
512            a: None,
513            b: None,
514            c: None,
515            d: true,
516        };
517        // Sequence tag (0x30), length 3
518        // Boolean 'd' is implicitly tagged with [3]: tag (0x83), length 1, value TRUE (0xFF)
519        let expected1 = &[0x30, 0x03, 0x83, 0x01, 0xFF];
520        assert_eq!(encode(&value1).unwrap(), expected1);
521        assert_eq!(decode::<TestSequence>(expected1).unwrap(), value1);
522
523        // Case 2: 'a' is present, others absent.
524        let value2 = TestSequence {
525            a: Some(10),
526            b: None,
527            c: None,
528            d: true,
529        };
530        // Sequence tag (0x30), length 6
531        // Integer 'a' is implicitly tagged with [0]: tag (0x80), length 1, value 10
532        // Boolean 'd' is implicitly tagged with [3]: tag (0x83), length 1, value TRUE
533        let expected2 = &[0x30, 0x06, 0x80, 0x01, 0x0A, 0x83, 0x01, 0xFF];
534        assert_eq!(encode(&value2).unwrap(), expected2);
535        assert_eq!(decode::<TestSequence>(expected2).unwrap(), value2);
536
537        // Case 3: 'b' is present (as Integer), others absent.
538        let value3 = TestSequence {
539            a: None,
540            b: Some(TestChoice::Integer(20)),
541            c: None,
542            d: true,
543        };
544        // Sequence tag (0x30), length 8
545        // Choice 'b' is explicitly tagged with [1]: tag (0xA1), constructed, length 3
546        // Integer variant is implicitly tagged with [0]: tag (0x80), length 1, value 20
547        // Boolean 'd' is implicitly tagged with [3]: tag (0x83), length 1, value TRUE
548        let expected3 = &[0x30, 0x08, 0xA1, 0x03, 0x80, 0x01, 0x14, 0x83, 0x01, 0xFF];
549        assert_eq!(encode(&value3).unwrap(), expected3);
550        assert_eq!(decode::<TestSequence>(expected3).unwrap(), value3);
551
552        // Case 4: 'c' is present, others absent.
553        let any_payload = &[0x05, 0x00]; // NULL type
554        let value4 = TestSequence {
555            a: None,
556            b: None,
557            c: Some(Any::new(any_payload.to_vec())),
558            d: true,
559        };
560        // Sequence tag (0x30), length 7
561        // Any 'c' is implicitly tagged with [2]: tag (0x82), length 2, value [0x05, 0x00]
562        // Boolean 'd' is implicitly tagged with [3]: tag (0x83), length 1, value TRUE
563        let expected4 = &[0x30, 0x07, 0x82, 0x02, 0x05, 0x00, 0x83, 0x01, 0xFF];
564        assert_eq!(encode(&value4).unwrap(), expected4);
565        assert_eq!(decode::<TestSequence>(expected4).unwrap(), value4);
566
567        // Case 5: All optional fields present.
568        let value5 = TestSequence {
569            a: Some(255),
570            b: Some(TestChoice::Boolean(false)),
571            c: Some(Any::new(any_payload.to_vec())),
572            d: false,
573        };
574        // Sequence tag (0x30), length 16
575        // 'a' (u32, 255): implicitly tagged with [0] -> 80 02 00 FF
576        // 'b' (TestChoice::Boolean(false)): explicitly tagged with [1] -> A1 03 (content)
577        //   'Boolean' variant implicitly tagged with [1] -> 81 01 00
578        // 'c' (Any): implicitly tagged with [2] -> 82 02 05 00
579        // 'd' (bool, false): implicitly tagged with [3] -> 83 01 00
580        let expected5 = &[
581            0x30, 0x10, 0x80, 0x02, 0x00, 0xFF, 0xA1, 0x03, 0x81, 0x01, 0x00, 0x82, 0x02, 0x05,
582            0x00, 0x83, 0x01, 0x00,
583        ];
584        assert_eq!(encode(&value5).unwrap(), expected5);
585        assert_eq!(decode::<TestSequence>(expected5).unwrap(), value5);
586
587        // Case 6: 'a' and 'c' are present.
588        let value6 = TestSequence {
589            a: Some(1),
590            b: None,
591            c: Some(Any::new(any_payload.to_vec())),
592            d: true,
593        };
594        // Sequence tag (0x30), length 10
595        // 'a' (u32, 1): implicitly tagged with [0] -> 80 01 01
596        // 'c' (Any): implicitly tagged with [2] -> 82 02 05 00
597        // 'd' (bool, true): implicitly tagged with [3] -> 83 01 FF
598        let expected6 = &[
599            0x30, 0x0A, 0x80, 0x01, 0x01, 0x82, 0x02, 0x05, 0x00, 0x83, 0x01, 0xFF,
600        ];
601        assert_eq!(encode(&value6).unwrap(), expected6);
602        assert_eq!(decode::<TestSequence>(expected6).unwrap(), value6);
603
604        // Another type where the final field is optional
605        #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
606        #[rasn(automatic_tags)]
607        pub struct AnotherTestSequence {
608            a: Option<TestChoice>,
609            b: Option<Any>,
610        }
611        let value1 = AnotherTestSequence { a: None, b: None };
612        // Sequence tag (0x30), length 0
613        let expected1 = &[0x30, 0x00];
614        assert_eq!(encode(&value1).unwrap(), expected1);
615        assert_eq!(decode::<AnotherTestSequence>(expected1).unwrap(), value1);
616        let value2 = AnotherTestSequence {
617            a: Some(TestChoice::Boolean(true)),
618            b: None,
619        };
620        // Sequence tag (0x30), length 5
621        // 'a' (TestChoice): explicitly tagged with [0] -> A0 03
622        // 'Boolean' (bool, true): implicitly tagged with [1] -> 81 01 FF
623        let expected2 = &[0x30, 0x05, 0xA0, 0x03, 0x81, 0x01, 0xFF];
624        assert_eq!(encode(&value2).unwrap(), expected2);
625        assert_eq!(decode::<AnotherTestSequence>(expected2).unwrap(), value2);
626        let value3 = AnotherTestSequence {
627            a: None,
628            b: Some(Any::new(any_payload.to_vec())),
629        };
630        // Sequence tag (0x30), length 4
631        // 'b' (Any, NULL): implicitly tagged with [1] -> 81 02 05 00
632        let expected3 = &[0x30, 0x04, 0x81, 0x02, 0x05, 0x00];
633        assert_eq!(encode(&value3).unwrap(), expected3);
634    }
635
636    #[test]
637    fn test_cow_passthrough() {
638        use crate as rasn;
639        use rasn::prelude::*;
640
641        #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
642        struct MyType {
643            name: Utf8String,
644            data: OctetString,
645        }
646
647        let my_type = MyType {
648            name: "test1".into(),
649            data: OctetString::from(vec![0, 1, 2, 3]),
650        };
651
652        let my_type_plain_ser = encode(&my_type).unwrap();
653        let my_type_cow_ser = encode(&Cow::Borrowed(&my_type)).unwrap();
654
655        assert_eq!(my_type_plain_ser, my_type_cow_ser);
656
657        let my_type_des_plain = decode::<MyType>(&my_type_plain_ser).unwrap();
658        let my_type_des_cow = decode::<Cow<'_, MyType>>(&my_type_cow_ser).unwrap();
659
660        assert_eq!(my_type_des_plain.name, Utf8String::from("test1"));
661        assert_eq!(my_type_des_plain.data, OctetString::from(vec![0, 1, 2, 3]));
662        assert_eq!(my_type_des_plain.name, my_type_des_cow.name);
663        assert_eq!(my_type_des_plain.data, my_type_des_cow.data);
664
665        assert!(matches!(my_type_des_cow, Cow::Owned(_)));
666    }
667}