1mod config;
4
5use alloc::{borrow::ToOwned, collections::VecDeque, string::ToString, vec::Vec};
6use chrono::Timelike;
7
8use super::Identifier;
9use crate::{
10 bits::octet_string_ascending,
11 types::{
12 self,
13 oid::{MAX_OID_FIRST_OCTET, MAX_OID_SECOND_OCTET},
14 Constraints, Enumerated, Tag,
15 },
16 Codec, Encode,
17};
18
19pub use crate::error::{BerEncodeErrorKind, EncodeError, EncodeErrorKind};
20pub use config::EncoderOptions;
21
22const START_OF_CONTENTS: u8 = 0x80;
23const END_OF_CONTENTS: &[u8] = &[0, 0];
24
25pub struct Encoder {
27 output: Vec<u8>,
28 config: EncoderOptions,
29 is_set_encoding: bool,
30 set_buffer: alloc::collections::BTreeMap<Tag, Vec<u8>>,
31}
32
33enum ByteOrBytes {
35 Single(u8),
36 Many(Vec<u8>),
37}
38
39impl Encoder {
40 #[must_use]
42 pub fn new(config: EncoderOptions) -> Self {
43 Self {
44 config,
45 is_set_encoding: false,
46 output: <_>::default(),
47 set_buffer: <_>::default(),
48 }
49 }
50 #[must_use]
51 pub fn codec(&self) -> crate::Codec {
52 self.config.current_codec()
53 }
54
55 #[must_use]
58 pub fn new_set(config: EncoderOptions) -> Self {
59 Self {
60 config,
61 is_set_encoding: true,
62 output: <_>::default(),
63 set_buffer: <_>::default(),
64 }
65 }
66
67 pub fn new_with_buffer(config: EncoderOptions, mut buffer: Vec<u8>) -> Self {
72 buffer.clear();
73 Self {
74 output: buffer,
75 config,
76 is_set_encoding: false,
77 set_buffer: <_>::default(),
78 }
79 }
80
81 pub fn output(self) -> Vec<u8> {
83 if self.is_set_encoding {
84 self.set_buffer
85 .into_values()
86 .fold(Vec::new(), |mut acc, mut field| {
87 acc.append(&mut field);
88 acc
89 })
90 } else {
91 self.output
92 }
93 }
94
95 fn append_byte_or_bytes(&mut self, bytes: ByteOrBytes) {
96 match bytes {
97 ByteOrBytes::Single(b) => self.output.push(b),
98 ByteOrBytes::Many(mut bs) => self.output.append(&mut bs),
99 }
100 }
101
102 pub(super) fn encode_as_base128(&self, number: u32, buffer: &mut Vec<u8>) {
103 const WIDTH: u8 = 7;
104 const SEVEN_BITS: u8 = 0x7F;
105 const EIGHTH_BIT: u8 = 0x80;
106
107 if number < EIGHTH_BIT as u32 {
108 buffer.push(number as u8);
109 } else {
110 let mut n: u8;
111 let mut bits_left = 35;
112 let mut cont = false;
113 while bits_left > 0 {
114 bits_left -= WIDTH;
115 n = ((number >> bits_left) as u8) & SEVEN_BITS;
116 if n > 0 || cont {
117 buffer.push(if bits_left > 0 { EIGHTH_BIT } else { 0 } | (n & SEVEN_BITS));
118 cont = true;
119 }
120 }
121 }
122 }
123
124 fn encode_identifier(
137 &mut self,
138 Identifier {
139 tag,
140 is_constructed,
141 }: Identifier,
142 ) -> ByteOrBytes {
143 const FIVE_BITS: u32 = (1 << 5) - 1;
144 let mut tag_byte = tag.class as u8;
145 let tag_number = tag.value;
146
147 tag_byte <<= 1;
149 tag_byte |= match tag {
150 Tag::EXTERNAL | Tag::SEQUENCE | Tag::SET => 1,
151 _ if is_constructed => 1,
152 _ => 0,
153 };
154
155 tag_byte <<= 5;
156
157 if tag_number >= FIVE_BITS {
158 let mut buffer = alloc::vec![tag_byte | FIVE_BITS as u8];
159 self.encode_as_base128(tag_number, &mut buffer);
160 ByteOrBytes::Many(buffer)
161 } else {
162 tag_byte |= tag_number as u8;
163 ByteOrBytes::Single(tag_byte)
164 }
165 }
166
167 fn encode_length(&mut self, identifier: Identifier, value: &[u8]) {
168 if identifier.is_primitive() || !self.config.encoding_rules.is_cer() {
169 let len_bytes = self.encode_definite_length(value.len());
170 self.append_byte_or_bytes(len_bytes);
171 self.output.extend_from_slice(value);
172 } else {
173 self.output.push(START_OF_CONTENTS);
174 self.output.extend_from_slice(value);
175 self.output.extend_from_slice(END_OF_CONTENTS);
176 }
177 }
178
179 fn encode_definite_length(&mut self, len: usize) -> ByteOrBytes {
180 if len <= 127 {
181 ByteOrBytes::Single(len as u8)
182 } else {
183 let mut length = len;
184 let mut length_buffer = VecDeque::new();
185
186 while length != 0 {
187 length_buffer.push_front((length & 0xff) as u8);
188 length >>= 8;
189 }
190
191 length_buffer.push_front(length_buffer.len() as u8 | 0x80);
192
193 ByteOrBytes::Many(length_buffer.into())
194 }
195 }
196
197 fn encode_octet_string_(&mut self, tag: Tag, value: &[u8]) -> Result<(), EncodeError> {
198 self.encode_string(tag, Tag::OCTET_STRING, value)
199 }
200
201 fn encode_string(
205 &mut self,
206 tag: Tag,
207 nested_tag: Tag,
208 value: &[u8],
209 ) -> Result<(), EncodeError> {
210 let max_string_length = self.config.encoding_rules.max_string_length();
211
212 if value.len() > max_string_length {
213 let ident_bytes = self.encode_identifier(Identifier::from_tag(tag, true));
214 self.append_byte_or_bytes(ident_bytes);
215
216 self.output.push(START_OF_CONTENTS);
217
218 for chunk in value.chunks(max_string_length) {
219 self.encode_primitive(nested_tag, chunk);
220 }
221
222 self.output.extend_from_slice(END_OF_CONTENTS);
223 self.encode_to_set(tag);
224 } else {
225 self.encode_primitive(tag, value);
226 }
227
228 Ok(())
229 }
230
231 fn encode_primitive(&mut self, tag: Tag, value: &[u8]) {
232 self.encode_value(Identifier::from_tag(tag, false), value);
233 }
234
235 fn encode_constructed(&mut self, tag: Tag, value: &[u8]) {
236 self.encode_value(Identifier::from_tag(tag, true), value);
237 }
238
239 fn encode_value(&mut self, identifier: Identifier, value: &[u8]) {
241 let ident_bytes = self.encode_identifier(identifier);
242 self.append_byte_or_bytes(ident_bytes);
243 self.encode_length(identifier, value);
244 self.encode_to_set(identifier.tag);
245 }
246
247 fn encode_to_set(&mut self, tag: Tag) {
250 if self.is_set_encoding {
251 self.set_buffer
252 .insert(tag, core::mem::take(&mut self.output));
253 }
254 }
255 pub fn object_identifier_as_bytes(&mut self, oid: &[u32]) -> Result<Vec<u8>, EncodeError> {
258 if oid.len() < 2 {
259 return Err(BerEncodeErrorKind::invalid_object_identifier(oid.to_owned()).into());
260 }
261 let mut bytes = Vec::new();
262
263 let first = oid[0];
264 let second = oid[1];
265
266 if first > MAX_OID_FIRST_OCTET {
267 return Err(BerEncodeErrorKind::invalid_object_identifier(oid.to_owned()).into());
268 }
269 self.encode_as_base128((first * (MAX_OID_SECOND_OCTET + 1)) + second, &mut bytes);
270 for component in oid.iter().skip(2) {
271 self.encode_as_base128(*component, &mut bytes);
272 }
273 Ok(bytes)
274 }
275 #[must_use]
276 pub fn datetime_to_canonical_generalized_time_bytes(
279 value: &chrono::DateTime<chrono::FixedOffset>,
280 ) -> Vec<u8> {
281 let mut string;
282 let value = value.naive_utc();
284 if value.nanosecond() > 0 {
285 string = value.format("%Y%m%d%H%M%S.%f").to_string();
286 while string.ends_with('0') {
288 string.pop();
289 }
290 } else {
291 string = value.format("%Y%m%d%H%M%S").to_string();
292 }
293 string.push('Z');
294 string.into_bytes()
295 }
296
297 #[must_use]
298 pub fn datetime_to_canonical_utc_time_bytes(value: &chrono::DateTime<chrono::Utc>) -> Vec<u8> {
301 value
302 .naive_utc()
303 .format("%y%m%d%H%M%SZ")
304 .to_string()
305 .into_bytes()
306 }
307}
308
309impl crate::Encoder for Encoder {
310 type Ok = ();
311 type Error = EncodeError;
312
313 fn codec(&self) -> Codec {
314 Self::codec(self)
315 }
316 fn encode_any(&mut self, _: Tag, value: &types::Any) -> Result<Self::Ok, Self::Error> {
317 if self.is_set_encoding {
318 return Err(BerEncodeErrorKind::AnyInSet.into());
319 }
320
321 self.output.extend_from_slice(&value.contents);
322
323 Ok(())
324 }
325
326 fn encode_bit_string(
327 &mut self,
328 tag: Tag,
329 _constraints: Constraints,
330 value: &types::BitStr,
331 ) -> Result<Self::Ok, Self::Error> {
332 if value.is_empty() {
333 self.encode_primitive(tag, &[]);
334 Ok(())
335 } else {
336 let bit_length = value.len();
337 let vec = value.to_bitvec();
338 let bytes = vec.as_raw_slice();
339 let unused_bits: u8 = ((bytes.len() * 8) - bit_length).try_into().map_err(|err| {
340 EncodeError::from_kind(
341 EncodeErrorKind::FailedBitStringUnusedBitsToU8 { err },
342 self.codec(),
343 )
344 })?;
345 let mut encoded = Vec::with_capacity(bytes.len() + 1);
346 encoded.push(unused_bits);
347 encoded.extend(bytes);
348
349 self.encode_string(tag, Tag::BIT_STRING, &encoded)
350 }
351 }
352
353 fn encode_bool(&mut self, tag: Tag, value: bool) -> Result<Self::Ok, Self::Error> {
354 self.encode_primitive(tag, &[if value { 0xff } else { 0x00 }]);
355 Ok(())
356 }
357
358 fn encode_choice<E: Encode>(
359 &mut self,
360 _: Constraints,
361 _t: Tag,
362 encode_fn: impl FnOnce(&mut Self) -> Result<Tag, Self::Error>,
363 ) -> Result<Self::Ok, Self::Error> {
364 (encode_fn)(self).map(drop)
365 }
366
367 fn encode_enumerated<E: Enumerated>(
368 &mut self,
369 tag: Tag,
370 value: &E,
371 ) -> Result<Self::Ok, Self::Error> {
372 let value = E::discriminant(value);
373 self.encode_integer(tag, <_>::default(), &value.into())
374 }
375
376 fn encode_integer(
377 &mut self,
378 tag: Tag,
379 _constraints: Constraints,
380 value: &num_bigint::BigInt,
381 ) -> Result<Self::Ok, Self::Error> {
382 self.encode_primitive(tag, &value.to_signed_bytes_be());
383 Ok(())
384 }
385
386 fn encode_null(&mut self, tag: Tag) -> Result<Self::Ok, Self::Error> {
387 self.encode_primitive(tag, &[]);
388 Ok(())
389 }
390
391 fn encode_object_identifier(&mut self, tag: Tag, oid: &[u32]) -> Result<Self::Ok, Self::Error> {
392 let bytes = self.object_identifier_as_bytes(oid)?;
393 self.encode_primitive(tag, &bytes);
394 Ok(())
395 }
396
397 fn encode_octet_string(
398 &mut self,
399 tag: Tag,
400 _constraints: Constraints,
401 value: &[u8],
402 ) -> Result<Self::Ok, Self::Error> {
403 self.encode_octet_string_(tag, value)
404 }
405
406 fn encode_visible_string(
407 &mut self,
408 tag: Tag,
409 _constraints: Constraints,
410 value: &types::VisibleString,
411 ) -> Result<Self::Ok, Self::Error> {
412 self.encode_octet_string_(tag, value.as_iso646_bytes())
413 }
414
415 fn encode_ia5_string(
416 &mut self,
417 tag: Tag,
418 _constraints: Constraints,
419 value: &types::Ia5String,
420 ) -> Result<Self::Ok, Self::Error> {
421 self.encode_octet_string_(tag, value.as_iso646_bytes())
422 }
423
424 fn encode_general_string(
425 &mut self,
426 tag: Tag,
427 _constraints: Constraints,
428 value: &types::GeneralString,
429 ) -> Result<Self::Ok, Self::Error> {
430 self.encode_octet_string_(tag, value)
431 }
432
433 fn encode_printable_string(
434 &mut self,
435 tag: Tag,
436 _constraints: Constraints,
437 value: &types::PrintableString,
438 ) -> Result<Self::Ok, Self::Error> {
439 self.encode_octet_string_(tag, value.as_bytes())
440 }
441
442 fn encode_numeric_string(
443 &mut self,
444 tag: Tag,
445 _constraints: Constraints,
446 value: &types::NumericString,
447 ) -> Result<Self::Ok, Self::Error> {
448 self.encode_octet_string_(tag, value.as_bytes())
449 }
450
451 fn encode_teletex_string(
452 &mut self,
453 tag: Tag,
454 _: Constraints,
455 value: &types::TeletexString,
456 ) -> Result<Self::Ok, Self::Error> {
457 self.encode_octet_string_(tag, value)
458 }
459
460 fn encode_bmp_string(
461 &mut self,
462 tag: Tag,
463 _constraints: Constraints,
464 value: &types::BmpString,
465 ) -> Result<Self::Ok, Self::Error> {
466 self.encode_octet_string_(tag, &value.to_bytes())
467 }
468
469 fn encode_utf8_string(
470 &mut self,
471 tag: Tag,
472 _: Constraints,
473 value: &str,
474 ) -> Result<Self::Ok, Self::Error> {
475 self.encode_octet_string_(tag, value.as_bytes())
476 }
477
478 fn encode_utc_time(
479 &mut self,
480 tag: Tag,
481 value: &types::UtcTime,
482 ) -> Result<Self::Ok, Self::Error> {
483 self.encode_primitive(
484 tag,
485 Self::datetime_to_canonical_utc_time_bytes(value).as_slice(),
486 );
487
488 Ok(())
489 }
490
491 fn encode_generalized_time(
492 &mut self,
493 tag: Tag,
494 value: &types::GeneralizedTime,
495 ) -> Result<Self::Ok, Self::Error> {
496 self.encode_primitive(
497 tag,
498 Self::datetime_to_canonical_generalized_time_bytes(value).as_slice(),
499 );
500
501 Ok(())
502 }
503
504 fn encode_some<E: Encode>(&mut self, value: &E) -> Result<Self::Ok, Self::Error> {
505 value.encode(self)
506 }
507
508 fn encode_some_with_tag<E: Encode>(
509 &mut self,
510 tag: Tag,
511 value: &E,
512 ) -> Result<Self::Ok, Self::Error> {
513 value.encode_with_tag(self, tag)
514 }
515
516 fn encode_some_with_tag_and_constraints<E: Encode>(
517 &mut self,
518 tag: Tag,
519 constraints: Constraints,
520 value: &E,
521 ) -> Result<Self::Ok, Self::Error> {
522 value.encode_with_tag_and_constraints(self, tag, constraints)
523 }
524
525 fn encode_none<E: Encode>(&mut self) -> Result<Self::Ok, Self::Error> {
526 self.encode_none_with_tag(E::TAG)
527 }
528
529 fn encode_none_with_tag(&mut self, _: Tag) -> Result<Self::Ok, Self::Error> {
530 Ok(())
531 }
532
533 fn encode_sequence_of<E: Encode>(
534 &mut self,
535 tag: Tag,
536 values: &[E],
537 _constraints: Constraints,
538 ) -> Result<Self::Ok, Self::Error> {
539 let mut sequence_encoder = Self::new(self.config);
540
541 for value in values {
542 value.encode(&mut sequence_encoder)?;
543 }
544
545 self.encode_constructed(tag, &sequence_encoder.output);
546
547 Ok(())
548 }
549
550 fn encode_set_of<E: Encode>(
551 &mut self,
552 tag: Tag,
553 values: &types::SetOf<E>,
554 _constraints: Constraints,
555 ) -> Result<Self::Ok, Self::Error> {
556 let mut encoded_values = values
557 .iter()
558 .map(|val| {
559 let mut sequence_encoder = Self::new(self.config);
560 val.encode(&mut sequence_encoder)
561 .map(|_| sequence_encoder.output)
562 })
563 .collect::<Result<Vec<Vec<u8>>, _>>()?;
564
565 encoded_values.sort_by(octet_string_ascending);
568 let sorted_elements: Vec<u8> = encoded_values.into_iter().flatten().collect();
569
570 self.encode_constructed(tag, &sorted_elements);
571
572 Ok(())
573 }
574
575 fn encode_explicit_prefix<V: Encode>(
576 &mut self,
577 tag: Tag,
578 value: &V,
579 ) -> Result<Self::Ok, Self::Error> {
580 let mut encoder = Self::new(self.config);
581 value.encode(&mut encoder)?;
582 self.encode_constructed(tag, &encoder.output);
583 Ok(())
584 }
585
586 fn encode_sequence<C, F>(&mut self, tag: Tag, encoder_scope: F) -> Result<Self::Ok, Self::Error>
587 where
588 C: crate::types::Constructed,
589 F: FnOnce(&mut Self) -> Result<Self::Ok, Self::Error>,
590 {
591 let mut encoder = Self::new(self.config);
592
593 (encoder_scope)(&mut encoder)?;
594
595 self.encode_constructed(tag, &encoder.output);
596
597 Ok(())
598 }
599
600 fn encode_set<C, F>(&mut self, tag: Tag, encoder_scope: F) -> Result<Self::Ok, Self::Error>
601 where
602 C: crate::types::Constructed,
603 F: FnOnce(&mut Self) -> Result<Self::Ok, Self::Error>,
604 {
605 let mut encoder = Self::new_set(self.config);
606
607 (encoder_scope)(&mut encoder)?;
608
609 self.encode_constructed(tag, &encoder.output());
610
611 Ok(())
612 }
613
614 fn encode_extension_addition<E: Encode>(
615 &mut self,
616 tag: Tag,
617 constraints: Constraints,
618 value: E,
619 ) -> Result<Self::Ok, Self::Error> {
620 value.encode_with_tag_and_constraints(self, tag, constraints)
621 }
622
623 fn encode_extension_addition_group<E>(
625 &mut self,
626 value: Option<&E>,
627 ) -> Result<Self::Ok, Self::Error>
628 where
629 E: Encode + crate::types::Constructed,
630 {
631 value.encode(self)
632 }
633}
634
635#[cfg(test)]
636mod tests {
637 use super::*;
638 use alloc::borrow::ToOwned;
639 use alloc::vec;
640
641 #[derive(Clone, Copy, Hash, Debug, PartialEq)]
642 struct C0;
643 impl crate::AsnType for C0 {
644 const TAG: Tag = Tag::new(crate::types::Class::Context, 0);
645 }
646
647 #[test]
648 fn bit_string() {
649 let bitstring =
650 types::BitString::from_vec([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..].to_owned());
651
652 let primitive_encoded = &[0x03, 0x07, 0x00, 0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..];
653
654 assert_eq!(primitive_encoded, super::super::encode(&bitstring).unwrap());
655 }
656
657 #[test]
658 fn identifier() {
659 fn ident_to_bytes(ident: Identifier) -> Vec<u8> {
660 let mut enc = Encoder::new(EncoderOptions::ber());
661 let bytes = enc.encode_identifier(ident);
662 enc.append_byte_or_bytes(bytes);
663 enc.output
664 }
665
666 assert_eq!(
667 &[0xFF, 0x7F,][..],
668 ident_to_bytes(Identifier::from_tag(
669 Tag::new(crate::types::Class::Private, 127),
670 true,
671 ))
672 );
673 }
674
675 #[test]
676 fn encoding_oid() {
677 fn oid_to_bytes(oid: &[u32]) -> Vec<u8> {
678 use crate::Encoder;
679 let mut enc = self::Encoder::new(EncoderOptions::ber());
680 enc.encode_object_identifier(Tag::OBJECT_IDENTIFIER, oid)
681 .unwrap();
682 enc.output
683 }
684
685 assert_eq!(
687 &vec![0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01],
688 &oid_to_bytes(&[1, 3, 6, 1, 5, 5, 7, 48, 1])
689 );
690
691 assert_eq!(
693 &vec![0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x14],
694 &oid_to_bytes(&[1, 3, 6, 1, 4, 1, 311, 21, 20])
695 );
696
697 assert_eq!(
699 &vec![0x06, 0x03, 0x55, 0x04, 0x03],
700 &oid_to_bytes(&[2, 5, 4, 3])
701 );
702
703 assert_eq!(
705 &vec![0x06, 0x03, 0x88, 0x37, 0x01],
706 &oid_to_bytes(&[2, 999, 1])
707 );
708 }
709
710 #[test]
711 fn base128_test() {
712 fn encode(n: u32) -> Vec<u8> {
713 let enc = self::Encoder::new(EncoderOptions::ber());
714 let mut buffer: Vec<u8> = vec![];
715 enc.encode_as_base128(n, &mut buffer);
716 buffer
717 }
718
719 assert_eq!(&vec![0x0], &encode(0x0));
720 assert_eq!(&vec![0x7F], &encode(0x7F));
721 assert_eq!(&vec![0x81, 0x00], &encode(0x80));
722 assert_eq!(&vec![0xC0, 0x00], &encode(0x2000));
723 assert_eq!(&vec![0xFF, 0x7F], &encode(0x3FFF));
724 assert_eq!(&vec![0x81, 0x80, 0x00], &encode(0x4000));
725 assert_eq!(&vec![0xFF, 0xFF, 0x7F], &encode(0x001FFFFF));
726 assert_eq!(&vec![0x81, 0x80, 0x80, 0x00], &encode(0x00200000));
727 assert_eq!(&vec![0xC0, 0x80, 0x80, 0x00], &encode(0x08000000));
728 assert_eq!(&vec![0xFF, 0xFF, 0xFF, 0x7F], &encode(0x0FFFFFFF));
729 }
730
731 #[test]
732 fn any() {
733 let bitstring =
734 types::BitString::from_vec([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..].to_owned());
735
736 let primitive_encoded = &[0x03, 0x07, 0x00, 0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..];
737 let any = types::Any {
738 contents: primitive_encoded.into(),
739 };
740
741 assert_eq!(primitive_encoded, super::super::encode(&bitstring).unwrap());
742 assert_eq!(
743 super::super::encode(&bitstring).unwrap(),
744 super::super::encode(&any).unwrap()
745 );
746 }
747
748 #[test]
749 fn set() {
750 use crate::{
751 types::{AsnType, Implicit},
752 Encoder as _,
753 };
754
755 struct C0;
756 struct C1;
757 struct C2;
758
759 impl AsnType for C0 {
760 const TAG: Tag = Tag::new(crate::types::Class::Context, 0);
761 }
762
763 impl AsnType for C1 {
764 const TAG: Tag = Tag::new(crate::types::Class::Context, 1);
765 }
766
767 impl AsnType for C2 {
768 const TAG: Tag = Tag::new(crate::types::Class::Context, 2);
769 }
770
771 type Field1 = Implicit<C0, u32>;
772 type Field2 = Implicit<C1, u32>;
773 type Field3 = Implicit<C2, u32>;
774
775 let field1: Field1 = 1.into();
776 let field2: Field2 = 2.into();
777 let field3: Field3 = 3.into();
778
779 struct Set;
780
781 impl crate::types::Constructed for Set {
782 const FIELDS: crate::types::fields::Fields =
783 crate::types::fields::Fields::from_static(&[
784 crate::types::fields::Field::new_required(C0::TAG, C0::TAG_TREE, "field1"),
785 crate::types::fields::Field::new_required(C1::TAG, C1::TAG_TREE, "field2"),
786 crate::types::fields::Field::new_required(C2::TAG, C2::TAG_TREE, "field3"),
787 ]);
788 }
789
790 let output = {
791 let mut encoder = Encoder::new_set(EncoderOptions::ber());
792 encoder
793 .encode_set::<Set, _>(Tag::SET, |encoder| {
794 field3.encode(encoder)?;
795 field2.encode(encoder)?;
796 field1.encode(encoder)?;
797 Ok(())
798 })
799 .unwrap();
800
801 encoder.output()
802 };
803
804 assert_eq!(
805 vec![0x31, 0x9, 0x80, 0x1, 0x1, 0x81, 0x1, 0x2, 0x82, 0x1, 0x3],
806 output,
807 );
808 }
809}