Skip to main content

rasn/per/
enc.rs

1//! Encoding Rust structures into Packed Encoding Rules data.
2
3use alloc::{borrow::ToOwned, string::ToString, vec::Vec};
4
5use bitvec::prelude::*;
6
7use super::{
8    FOURTY_EIGHT_K, LARGE_UNSIGNED_CONSTRAINT, SIXTEEN_K, SIXTY_FOUR_K, SMALL_UNSIGNED_CONSTRAINT,
9    THIRTY_TWO_K,
10};
11use crate::{
12    Encode,
13    types::{
14        self, BitString, Constraints, Enumerated, Identifier, IntegerType, Tag,
15        constraints::{self, Extensible, Size},
16        strings::{
17            BitStr, DynConstrainedCharacterString, StaticPermittedAlphabet, should_be_indexed,
18        },
19    },
20};
21
22pub use crate::error::EncodeError as Error;
23type Result<T, E = Error> = core::result::Result<T, E>;
24
25/// Options for configuring the [`Encoder`].
26#[derive(Debug, Clone, Copy, Default)]
27pub struct EncoderOptions {
28    aligned: bool,
29    set_encoding: bool,
30}
31
32impl EncoderOptions {
33    /// Returns the default encoder options for Aligned Packed Encoding Rules.
34    #[must_use]
35    pub fn aligned() -> Self {
36        Self {
37            aligned: true,
38            ..<_>::default()
39        }
40    }
41
42    /// Returns the default encoder options for Unaligned Packed Encoding Rules.
43    #[must_use]
44    pub fn unaligned() -> Self {
45        Self {
46            aligned: false,
47            ..<_>::default()
48        }
49    }
50
51    #[must_use]
52    fn without_set_encoding(mut self) -> Self {
53        self.set_encoding = false;
54        self
55    }
56    #[must_use]
57    fn current_codec(self) -> crate::Codec {
58        if self.aligned {
59            crate::Codec::Aper
60        } else {
61            crate::Codec::Uper
62        }
63    }
64}
65
66/// Encodes Rust data structures into Canonical Packed Encoding Rules (CPER) data.
67///
68/// Const `RCL` is the count of root components in the root component list of a sequence or set.
69/// Const `ECL` is the count of extension additions in the extension addition component type list in a sequence or set.
70#[derive(Debug)]
71pub struct Encoder<const RCL: usize = 0, const ECL: usize = 0> {
72    options: EncoderOptions,
73    output: BitString,
74    set_output: alloc::collections::BTreeMap<Tag, BitString>,
75    number_optional_default_fields: usize,
76    root_bitfield: (usize, [(bool, Tag); RCL]),
77    extension_bitfield: (usize, [bool; ECL]),
78    extension_fields: [Option<Vec<u8>>; ECL],
79    is_extension_sequence: bool,
80    parent_output_length: Option<usize>,
81}
82
83impl<const RCL: usize, const ECL: usize> Encoder<RCL, ECL> {
84    /// Constructs a new encoder from the provided options.
85    pub fn new(options: EncoderOptions) -> Self {
86        Self {
87            options,
88            output: <_>::default(),
89            set_output: <_>::default(),
90            number_optional_default_fields: 0,
91            root_bitfield: (0, [(false, Tag::new_private(0)); RCL]),
92            extension_bitfield: (0, [false; ECL]),
93            is_extension_sequence: <_>::default(),
94            extension_fields: [(); ECL].map(|_| None),
95            parent_output_length: <_>::default(),
96        }
97    }
98    fn codec(&self) -> crate::Codec {
99        self.options.current_codec()
100    }
101    fn new_set_encoder<const RL: usize, const EL: usize, C: crate::types::Constructed<RL, EL>>(
102        &self,
103    ) -> Encoder<RL, EL> {
104        let mut options = self.options;
105        options.set_encoding = true;
106        let mut encoder = Encoder::<RL, EL>::new(options);
107        encoder.number_optional_default_fields = C::FIELDS.number_of_optional_and_default_fields();
108        encoder.is_extension_sequence = C::IS_EXTENSIBLE;
109        encoder.parent_output_length = Some(self.output_length());
110        encoder
111    }
112
113    fn new_sequence_encoder<
114        const RL: usize,
115        const EL: usize,
116        C: crate::types::Constructed<RL, EL>,
117    >(
118        &self,
119    ) -> Encoder<RL, EL> {
120        let mut encoder = Encoder::<RL, EL>::new(self.options.without_set_encoding());
121        encoder.number_optional_default_fields = C::FIELDS.number_of_optional_and_default_fields();
122        encoder.is_extension_sequence = C::IS_EXTENSIBLE;
123        encoder.parent_output_length = Some(self.output_length());
124        encoder
125    }
126
127    /// Returns the octet aligned output for the encoder.
128    pub fn output(&mut self) -> Vec<u8> {
129        let mut output = self.bitstring_output();
130        Self::force_pad_to_alignment(&mut output);
131        output.as_raw_slice().to_vec()
132    }
133
134    /// Returns the bit level output for the encoder.
135    fn bitstring_output(&mut self) -> BitString {
136        if self.options.set_encoding {
137            self.set_output.values().flatten().collect::<BitString>()
138        } else {
139            core::mem::take(&mut *self.output.as_mut())
140        }
141    }
142
143    /// Sets the presence of a `OPTIONAL` or `DEFAULT` field in the bitfield.
144    /// The presence is ordered based on the field index.
145    fn set_presence(&mut self, tag: Tag, bit: bool) {
146        // Applies only for SEQUENCE and SET types (RCL > 0)
147        // Compiler should optimize this out
148        if RCL > 0 {
149            if self.number_optional_default_fields < self.root_bitfield.0 + 1 {
150                // Fields should be encoded in order
151                // When the presence of optional extension field is set, we end up here
152                // However, we don't need that information
153                return;
154            }
155            self.root_bitfield.1[self.root_bitfield.0] = (bit, tag);
156            self.root_bitfield.0 += 1;
157        }
158    }
159    fn set_extension_presence(&mut self, bit: bool) {
160        // Applies only for SEQUENCE and SET types (ECL > 0)
161        // Compiler should optimize this out when not present
162        if ECL > 0 {
163            self.extension_bitfield.1[self.extension_bitfield.0] = bit;
164            self.extension_bitfield.0 += 1;
165        }
166    }
167
168    fn output_length(&self) -> usize {
169        let mut output_length = self.output.len();
170        output_length += usize::from(self.is_extension_sequence);
171        output_length += self.number_optional_default_fields;
172        output_length += self.parent_output_length.unwrap_or_default();
173
174        if self.options.set_encoding {
175            output_length += self
176                .set_output
177                .values()
178                .map(bitvec::vec::BitVec::len)
179                .sum::<usize>();
180        }
181
182        output_length
183    }
184
185    fn pad_to_alignment(&self, buffer: &mut BitString) {
186        if self.options.aligned {
187            let mut output_length = self.output_length();
188            output_length += buffer.len();
189            if !output_length.is_multiple_of(8) {
190                for _ in 0..(8 - output_length % 8) {
191                    buffer.push(false);
192                }
193            }
194        }
195    }
196
197    fn force_pad_to_alignment(buffer: &mut BitString) {
198        const BYTE_WIDTH: usize = 8;
199        if !buffer.len().is_multiple_of(BYTE_WIDTH) {
200            let mut string = BitString::new();
201            for _ in 0..BYTE_WIDTH - (buffer.len() % 8) {
202                string.push(false);
203            }
204            buffer.extend(string);
205            debug_assert_eq!(0, buffer.len() % 8);
206        }
207    }
208
209    fn encode_extensible_bit(
210        &mut self,
211        constraints: &Constraints,
212        buffer: &mut BitString,
213        extensible_condition: impl FnOnce() -> bool,
214    ) -> bool {
215        if constraints.extensible() {
216            let is_in_constraints = !(extensible_condition)();
217            buffer.push(is_in_constraints);
218            is_in_constraints
219        } else {
220            <_>::default()
221        }
222    }
223
224    #[allow(clippy::too_many_lines)]
225    fn encode_known_multiplier_string<S: StaticPermittedAlphabet>(
226        &mut self,
227        tag: Tag,
228        constraints: &Constraints,
229        value: &S,
230    ) -> Result<()> {
231        use crate::types::constraints::Bounded;
232        let mut buffer = BitString::default();
233        let string_length = value.len();
234
235        let is_extended_value = self.encode_extensible_bit(constraints, &mut buffer, || {
236            constraints.size().is_some_and(|size_constraint| {
237                size_constraint.extensible.is_some()
238                    && size_constraint.constraint.contains(&string_length)
239            })
240        });
241
242        let is_large_string = if let Some(size) = constraints.size() {
243            let width = match constraints.permitted_alphabet() {
244                Some(alphabet) => self
245                    .character_width(crate::num::log2(alphabet.constraint.len() as i128) as usize),
246                None => self.character_width(S::CHARACTER_SET_WIDTH),
247            };
248
249            match *size.constraint {
250                Bounded::Range {
251                    start: Some(_),
252                    end: Some(_),
253                } if size.constraint.range().unwrap() * width as usize > 16 => true,
254                Bounded::Single(max) if max * width as usize > 16 => {
255                    self.pad_to_alignment(&mut buffer);
256                    true
257                }
258                Bounded::Range {
259                    start: None,
260                    end: Some(max),
261                } if max * width as usize > 16 => {
262                    self.pad_to_alignment(&mut buffer);
263                    true
264                }
265                _ => false,
266            }
267        } else {
268            false
269        };
270
271        match (
272            constraints.permitted_alphabet(),
273            should_be_indexed(S::CHARACTER_SET_WIDTH as u32, S::CHARACTER_SET),
274            constraints.permitted_alphabet().map(|alphabet| {
275                S::CHARACTER_SET_WIDTH
276                    > self.character_width(
277                        crate::num::log2(alphabet.constraint.len() as i128) as usize
278                    )
279            }),
280        ) {
281            (Some(alphabet), _, Some(true)) | (Some(alphabet), true, _) => {
282                let alphabet = &alphabet.constraint;
283                let characters = &DynConstrainedCharacterString::from_bits(value.chars(), alphabet)
284                    .map_err(|e| Error::alphabet_constraint_not_satisfied(e, self.codec()))?;
285
286                self.encode_length(
287                    &mut buffer,
288                    value.len(),
289                    is_extended_value
290                        .then(|| -> Extensible<Size> { <_>::default() })
291                        .as_ref()
292                        .or(constraints.size()),
293                    |range| Ok(characters[range].to_bitvec()),
294                )?;
295            }
296            (None, true, _) => {
297                let characters =
298                    &DynConstrainedCharacterString::from_bits(value.chars(), S::CHARACTER_SET)
299                        .map_err(|e| Error::alphabet_constraint_not_satisfied(e, self.codec()))?;
300
301                self.encode_length(
302                    &mut buffer,
303                    value.len(),
304                    is_extended_value
305                        .then(|| -> Extensible<Size> { <_>::default() })
306                        .as_ref()
307                        .or(constraints.size()),
308                    |range| Ok(characters[range].to_bitvec()),
309                )?;
310            }
311            _ => {
312                let char_length = value.len();
313                let octet_aligned_value = self.options.aligned.then(|| {
314                    if S::CHARACTER_SET_WIDTH <= self.character_width(S::CHARACTER_SET_WIDTH) {
315                        value.to_octet_aligned_string()
316                    } else {
317                        value.to_octet_aligned_index_string()
318                    }
319                });
320                // 30.5.4 Rec. ITU-T X.691 (02/2021)
321                let value = value.to_index_or_value_bitstring();
322
323                let octet_aligned_value = &octet_aligned_value;
324                self.encode_string_length(
325                    &mut buffer,
326                    is_large_string,
327                    char_length,
328                    is_extended_value
329                        .then(|| -> Extensible<Size> { <_>::default() })
330                        .as_ref()
331                        .or(constraints.size()),
332                    |range| {
333                        Ok(match octet_aligned_value {
334                            Some(value) => types::BitString::from_slice(&value[range]),
335                            None => value[S::char_range_to_bit_range(range)].to_bitvec(),
336                        })
337                    },
338                )?;
339            }
340        };
341
342        self.extend(tag, &buffer);
343        Ok(())
344    }
345
346    fn character_width(&self, width: usize) -> usize {
347        if self.options.aligned {
348            {
349                if width.is_power_of_two() {
350                    width
351                } else {
352                    width.next_power_of_two()
353                }
354            }
355        } else {
356            width
357        }
358    }
359
360    fn encode_constructed<
361        const RL: usize,
362        const EL: usize,
363        C: crate::types::Constructed<RL, EL>,
364    >(
365        &mut self,
366        tag: Tag,
367        mut encoder: Encoder<RL, EL>,
368    ) -> Result<()> {
369        let mut buffer = BitString::with_capacity(core::mem::size_of::<C>());
370        let mut extensions_present = false;
371        if C::IS_EXTENSIBLE {
372            extensions_present = encoder.extension_fields.iter().any(Option::is_some);
373            buffer.push(extensions_present);
374        }
375        let required_present = C::FIELDS.has_required_field();
376        let (needed, option_bitfield) = if encoder.options.set_encoding {
377            // In set encoding, tags must be unique so we just sort them to be in canonical order for preamble
378            encoder
379                .root_bitfield
380                .1
381                .sort_by(|(_, tag1), (_, tag2)| tag1.cmp(tag2));
382            encoder.root_bitfield
383        } else {
384            encoder.root_bitfield
385        };
386        debug_assert!(C::FIELDS.number_of_optional_and_default_fields() == needed);
387        if needed > 0 || C::IS_EXTENSIBLE {
388            for (bit, _tag) in &option_bitfield[..needed] {
389                buffer.push(*bit);
390            }
391        }
392        if option_bitfield[..needed].iter().any(|(bit, _tag)| *bit) || required_present {
393            let mut out = encoder.bitstring_output();
394            buffer.append(&mut out);
395        }
396
397        if !C::IS_EXTENSIBLE || !extensions_present {
398            self.extend(tag, &buffer);
399            return Ok(());
400        }
401        self.encode_normally_small_length(EL, &mut buffer)?;
402        for bit in encoder.extension_fields.iter() {
403            buffer.push(bit.is_some());
404        }
405
406        for field in encoder.extension_fields.iter().filter_map(Option::as_ref) {
407            self.encode_length(&mut buffer, field.len(), <_>::default(), |range| {
408                Ok(BitString::from_slice(&field[range]))
409            })?;
410        }
411        self.extend(tag, &buffer);
412
413        Ok(())
414    }
415
416    fn encode_normally_small_length(&mut self, value: usize, buffer: &mut BitString) -> Result<()> {
417        debug_assert!(value >= 1);
418        let value = if value >= 64 { value } else { value - 1 };
419        self.encode_normally_small_integer(value, buffer)
420    }
421
422    fn encode_normally_small_integer(
423        &mut self,
424        value: usize,
425        buffer: &mut BitString,
426    ) -> Result<()> {
427        let is_large = value >= 64;
428        buffer.push(is_large);
429
430        if is_large {
431            self.encode_integer_into_buffer::<usize>(LARGE_UNSIGNED_CONSTRAINT, &value, buffer)
432        } else {
433            self.encode_integer_into_buffer::<usize>(SMALL_UNSIGNED_CONSTRAINT, &value, buffer)
434        }
435    }
436
437    fn encode_string_length(
438        &self,
439        buffer: &mut BitString,
440        is_large_string: bool,
441        length: usize,
442        constraints: Option<&Extensible<constraints::Size>>,
443        encode_fn: impl Fn(core::ops::Range<usize>) -> Result<BitString>,
444    ) -> Result<()> {
445        let Some(constraints) = constraints else {
446            return self.encode_unconstrained_length(buffer, length, None, encode_fn);
447        };
448
449        if constraints.extensible.is_none() {
450            Error::check_length(length, &constraints.constraint, self.codec())?;
451        }
452
453        let constraints = constraints.constraint;
454
455        match constraints.start_and_end() {
456            (Some(_), Some(_)) => {
457                let range = constraints.range().unwrap();
458
459                if range == 0 {
460                    Ok(())
461                } else if range == 1 {
462                    buffer.extend((encode_fn)(0..length)?);
463                    Ok(())
464                } else if range <= SIXTY_FOUR_K as usize {
465                    let effective_length = constraints.effective_value(length).into_inner();
466                    let range = if self.options.aligned && range > 256 {
467                        {
468                            let range = crate::num::log2(range as i128);
469                            crate::bits::range_from_len(if range.is_power_of_two() {
470                                range
471                            } else {
472                                range.next_power_of_two()
473                            })
474                        }
475                    } else {
476                        range as i128
477                    };
478                    self.encode_non_negative_binary_integer(
479                        buffer,
480                        range,
481                        &(effective_length as u32).to_be_bytes(),
482                    );
483                    if is_large_string {
484                        self.pad_to_alignment(buffer);
485                    }
486
487                    buffer.extend((encode_fn)(0..length)?);
488                    Ok(())
489                } else {
490                    self.encode_unconstrained_length(buffer, length, None, encode_fn)
491                }
492            }
493            _ => self.encode_unconstrained_length(buffer, length, None, encode_fn),
494        }
495    }
496
497    fn encode_length(
498        &self,
499        buffer: &mut BitString,
500        length: usize,
501        constraints: Option<&Extensible<constraints::Size>>,
502        encode_fn: impl Fn(core::ops::Range<usize>) -> Result<BitString>,
503    ) -> Result<()> {
504        self.encode_string_length(buffer, false, length, constraints, encode_fn)
505    }
506
507    fn encode_unconstrained_length(
508        &self,
509        buffer: &mut BitString,
510        mut length: usize,
511        min: Option<usize>,
512        encode_fn: impl Fn(core::ops::Range<usize>) -> Result<BitString>,
513    ) -> Result<()> {
514        let mut min = min.unwrap_or_default();
515
516        self.pad_to_alignment(&mut *buffer);
517        if length <= 127 {
518            buffer.extend((length as u8).to_be_bytes());
519            buffer.extend((encode_fn)(0..length)?);
520        } else if length < SIXTEEN_K.into() {
521            const SIXTEENTH_BIT: u16 = 0x8000;
522            buffer.extend((SIXTEENTH_BIT | length as u16).to_be_bytes());
523            buffer.extend((encode_fn)(0..length)?);
524        } else {
525            loop {
526                // Hack to get around no exclusive syntax.
527                const K64: usize = SIXTY_FOUR_K as usize;
528                const K48: usize = FOURTY_EIGHT_K as usize;
529                const K32: usize = THIRTY_TWO_K as usize;
530                const K16: usize = SIXTEEN_K as usize;
531                const K64_MAX: usize = K64 - 1;
532                const K48_MAX: usize = K48 - 1;
533                const K32_MAX: usize = K32 - 1;
534                let (fragment_index, amount) = match length {
535                    K64..=usize::MAX => (4, K64),
536                    K48..=K64_MAX => (3, K48),
537                    K32..=K48_MAX => (2, K32),
538                    K16..=K32_MAX => (1, K16),
539                    _ => {
540                        break self.encode_unconstrained_length(
541                            buffer,
542                            length,
543                            Some(min),
544                            encode_fn,
545                        )?;
546                    }
547                };
548
549                const FRAGMENT_MARKER: u8 = 0xC0;
550                buffer.extend(&[FRAGMENT_MARKER | fragment_index]);
551
552                buffer.extend((encode_fn)(min..min + amount)?);
553                min += amount;
554
555                if length == SIXTEEN_K as usize {
556                    // Add final fragment in the frame.
557                    buffer.extend(&[0]);
558                    break;
559                }
560                length = length.saturating_sub(amount);
561            }
562        }
563
564        Ok(())
565    }
566
567    fn extend<'input>(&mut self, tag: Tag, input: impl Into<Input<'input>>) {
568        use bitvec::field::BitField;
569        let mut set_buffer = <_>::default();
570        let buffer = if self.options.set_encoding {
571            &mut set_buffer
572        } else {
573            &mut self.output
574        };
575
576        match input.into() {
577            Input::Bits(bits) => {
578                buffer.extend_from_bitslice(bits);
579            }
580            Input::Bit(bit) => {
581                buffer.push(bit);
582            }
583            Input::Byte(byte) => {
584                buffer.store_be(byte);
585            }
586            Input::Bytes(bytes) => {
587                buffer.extend(bytes);
588            }
589        }
590        if self.options.set_encoding {
591            self.set_output.insert(tag, set_buffer);
592        }
593    }
594
595    fn encode_octet_string_into_buffer(
596        &mut self,
597        constraints: Constraints,
598        value: &[u8],
599        buffer: &mut BitString,
600    ) -> Result<()> {
601        let octet_string_length = value.len();
602        let extensible_is_present = self.encode_extensible_bit(&constraints, buffer, || {
603            constraints.size().is_some_and(|size_constraint| {
604                size_constraint.extensible.is_some()
605                    && size_constraint.constraint.contains(&octet_string_length)
606            })
607        });
608        let Some(size) = constraints.size() else {
609            return self.encode_length(buffer, value.len(), <_>::default(), |range| {
610                Ok(BitString::from_slice(&value[range]))
611            });
612        };
613
614        if extensible_is_present {
615            self.encode_length(buffer, value.len(), <_>::default(), |range| {
616                Ok(BitString::from_slice(&value[range]))
617            })?;
618        } else if Some(0) == size.constraint.range() {
619            // ITU-T X.691 (02/2021) ยง11.9.3.3: If "n" is zero there shall be no further addition to the field-list.
620        } else if size.constraint.range() == Some(1) && size.constraint.as_start() <= Some(&2) {
621            // ITU-T X.691 (02/2021) ยง17 NOTE: Octet strings of fixed length less than or equal to two octets are not octet-aligned.
622            // All other octet strings are octet-aligned in the ALIGNED variant.
623            self.encode_length(buffer, value.len(), Some(size), |range| {
624                Ok(BitString::from_slice(&value[range]))
625            })?;
626        } else {
627            if size.constraint.range() == Some(1) {
628                self.pad_to_alignment(buffer);
629            }
630            self.encode_string_length(buffer, true, value.len(), Some(size), |range| {
631                Ok(BitString::from_slice(&value[range]))
632            })?;
633        }
634
635        Ok(())
636    }
637
638    #[allow(clippy::too_many_lines)]
639    fn encode_integer_into_buffer<I: IntegerType>(
640        &mut self,
641        constraints: Constraints,
642        value: &I,
643        buffer: &mut BitString,
644    ) -> Result<()> {
645        let is_extended_value = self.encode_extensible_bit(&constraints, buffer, || {
646            constraints.value().is_some_and(|value_range| {
647                value_range.extensible.is_some() && value_range.constraint.in_bound(value)
648            })
649        });
650
651        let value_range = if is_extended_value || constraints.value().is_none() {
652            let (bytes, needed) = value.to_signed_bytes_be();
653            self.encode_length(buffer, needed, constraints.size(), |range| {
654                Ok(BitString::from_slice(&bytes.as_ref()[..needed][range]))
655            })?;
656            return Ok(());
657        } else {
658            // Safe to unwrap because we checked for None above
659            constraints.value().unwrap()
660        };
661
662        if !value_range.constraint.in_bound(value) && !is_extended_value {
663            return Err(Error::value_constraint_not_satisfied(
664                value.to_bigint().unwrap_or_default(),
665                &value_range.constraint,
666                self.codec(),
667            ));
668        }
669
670        let effective_range = value_range
671            .constraint
672            .effective_value(value.to_i128().ok_or_else(|| {
673                Error::integer_type_conversion_failed(
674                    "Value too large for i128 type - outside of type constraint".to_string(),
675                    self.codec(),
676                )
677            })?);
678        let unsigned_ref;
679        let signed_ref;
680        let needed: usize;
681        let bytes = match &effective_range {
682            either::Left(offset) => {
683                (unsigned_ref, needed) = offset.to_unsigned_bytes_be();
684                unsigned_ref.as_ref()
685            }
686            either::Right(value) => {
687                (signed_ref, needed) = value.to_signed_bytes_be();
688                signed_ref.as_ref()
689            }
690        };
691
692        let effective_value: i128 = value_range
693            .constraint
694            .effective_value(value.to_i128().ok_or_else(|| {
695                Error::integer_type_conversion_failed(
696                    "Value too large for i128 type - outside of type constraint".to_string(),
697                    self.codec(),
698                )
699            })?)
700            .either_into();
701
702        const K64: i128 = SIXTY_FOUR_K as i128;
703        const OVER_K64: i128 = K64 + 1;
704
705        if let Some(range) = value_range.constraint.range() {
706            match (self.options.aligned, range) {
707                (true, 256) => {
708                    self.pad_to_alignment(buffer);
709                    self.encode_non_negative_binary_integer(buffer, range, &bytes[..needed]);
710                }
711                (true, 257..=K64) => {
712                    self.pad_to_alignment(buffer);
713                    self.encode_non_negative_binary_integer(buffer, K64, &bytes[..needed]);
714                }
715                (true, OVER_K64..) => {
716                    let range_len_in_bytes =
717                        i128::from(num_integer::div_ceil(crate::num::log2(range), 8));
718
719                    if effective_value == 0 {
720                        self.encode_non_negative_binary_integer(
721                            &mut *buffer,
722                            range_len_in_bytes,
723                            &[0],
724                        );
725                        self.pad_to_alignment(&mut *buffer);
726                        self.encode_non_negative_binary_integer(
727                            &mut *buffer,
728                            255,
729                            &bytes[..needed],
730                        );
731                    } else {
732                        let range_value_in_bytes = i128::from(num_integer::div_ceil(
733                            crate::num::log2(effective_value + 1),
734                            8,
735                        ));
736                        self.encode_non_negative_binary_integer(
737                            buffer,
738                            range_len_in_bytes,
739                            &(range_value_in_bytes - 1).to_be_bytes(),
740                        );
741                        self.pad_to_alignment(&mut *buffer);
742                        self.encode_non_negative_binary_integer(
743                            &mut *buffer,
744                            crate::bits::range_from_len(range_value_in_bytes as u32 * 8),
745                            &bytes[..needed],
746                        );
747                    }
748                }
749                (_, _) => self.encode_non_negative_binary_integer(buffer, range, &bytes[..needed]),
750            }
751        } else {
752            self.encode_length(buffer, needed, <_>::default(), |range| {
753                Ok(BitString::from_slice(&bytes[..needed][range]))
754            })?;
755        }
756
757        Ok(())
758    }
759
760    fn encode_non_negative_binary_integer(
761        &self,
762        buffer: &mut BitString,
763        range: i128,
764        bytes: &[u8],
765    ) {
766        use core::cmp::Ordering;
767        let total_bits = crate::num::log2(range) as usize;
768        let bits = BitVec::<u8, Msb0>::from_slice(bytes);
769        let bits = match total_bits.cmp(&bits.len()) {
770            Ordering::Greater => {
771                let mut padding = types::BitString::repeat(false, total_bits - bits.len());
772                padding.extend(bits);
773                padding
774            }
775            Ordering::Less => bits[bits.len() - total_bits..].to_owned(),
776            Ordering::Equal => bits,
777        };
778
779        // if !self.options.aligned && range >= super::TWO_FIFTY_SIX.into() {
780        //     self.pad_to_alignment(buffer);
781        // }
782
783        buffer.extend(bits);
784    }
785}
786
787impl<const RFC: usize, const EFC: usize> crate::Encoder<'_> for Encoder<RFC, EFC> {
788    type Ok = ();
789    type Error = Error;
790    type AnyEncoder<'this, const R: usize, const E: usize> = Encoder<R, E>;
791
792    fn codec(&self) -> crate::Codec {
793        Self::codec(self)
794    }
795
796    fn encode_any(
797        &mut self,
798        tag: Tag,
799        value: &types::Any,
800        _: Identifier,
801    ) -> Result<Self::Ok, Self::Error> {
802        self.encode_octet_string(
803            tag,
804            Constraints::default(),
805            value.as_bytes(),
806            Identifier::EMPTY,
807        )
808    }
809
810    fn encode_bit_string(
811        &mut self,
812        tag: Tag,
813        constraints: Constraints,
814        value: &BitStr,
815        _: Identifier,
816    ) -> Result<Self::Ok, Self::Error> {
817        let mut buffer = BitString::default();
818        let bit_string_length = value.len();
819        let extensible_is_present = self.encode_extensible_bit(&constraints, &mut buffer, || {
820            constraints.size().is_some_and(|size_constraint| {
821                size_constraint.extensible.is_some()
822                    && size_constraint.constraint.contains(&bit_string_length)
823            })
824        });
825        let size = constraints.size();
826
827        if extensible_is_present || size.is_none() {
828            self.encode_length(&mut buffer, value.len(), <_>::default(), |range| {
829                Ok(BitString::from(&value[range]))
830            })?;
831        } else if size.and_then(|size| size.constraint.range()) == Some(0) {
832            // NO-OP
833        } else if size.is_some_and(|size| {
834            size.constraint.range() == Some(1) && size.constraint.as_start() <= Some(&16)
835        }) {
836            // ITU-T X.691 (02/2021) ยง16: Bitstrings constrained to a fixed length less than or equal to 16 bits
837            // do not cause octet alignment. Larger bitstrings are octet-aligned in the ALIGNED variant.
838            self.encode_length(&mut buffer, value.len(), constraints.size(), |range| {
839                Ok(BitString::from(&value[range]))
840            })?;
841        } else {
842            if size.and_then(|size| size.constraint.range()) == Some(1) {
843                self.pad_to_alignment(&mut buffer);
844            }
845            self.encode_string_length(
846                &mut buffer,
847                true,
848                value.len(),
849                constraints.size(),
850                |range| Ok(BitString::from(&value[range])),
851            )?;
852        }
853
854        self.extend(tag, &buffer);
855        Ok(())
856    }
857
858    fn encode_bool(
859        &mut self,
860        tag: Tag,
861        value: bool,
862        _: Identifier,
863    ) -> Result<Self::Ok, Self::Error> {
864        self.extend(tag, value);
865        Ok(())
866    }
867
868    fn encode_enumerated<E: Enumerated>(
869        &mut self,
870        tag: Tag,
871        value: &E,
872        _: Identifier,
873    ) -> Result<Self::Ok, Self::Error> {
874        let mut buffer = BitString::default();
875        let index = value.enumeration_index();
876        if E::EXTENDED_VARIANTS.is_some() {
877            buffer.push(value.is_extended_variant());
878        }
879
880        if value.is_extended_variant() {
881            self.encode_normally_small_integer(index, &mut buffer)?;
882        } else if core::mem::size_of::<usize>() == 4 {
883            self.encode_non_negative_binary_integer(
884                &mut buffer,
885                E::variance() as i128,
886                &u32::try_from(index).unwrap().to_be_bytes(),
887            );
888        } else if core::mem::size_of::<usize>() == 2 {
889            self.encode_non_negative_binary_integer(
890                &mut buffer,
891                E::variance() as i128,
892                &u16::try_from(index).unwrap().to_be_bytes(),
893            );
894        } else {
895            self.encode_non_negative_binary_integer(
896                &mut buffer,
897                E::variance() as i128,
898                &usize::to_be_bytes(index)[..],
899            );
900        }
901
902        self.extend(tag, &buffer);
903        Ok(())
904    }
905
906    fn encode_integer<I: IntegerType>(
907        &mut self,
908        tag: Tag,
909        constraints: Constraints,
910        value: &I,
911        _: Identifier,
912    ) -> Result<Self::Ok, Self::Error> {
913        let mut buffer = BitString::new();
914        self.encode_integer_into_buffer(constraints, value, &mut buffer)?;
915        self.extend(tag, &buffer);
916        Ok(())
917    }
918
919    fn encode_real<R: types::RealType>(
920        &mut self,
921        _: Tag,
922        _: Constraints,
923        _: &R,
924        _: Identifier,
925    ) -> Result<Self::Ok, Self::Error> {
926        Err(Error::real_not_supported(self.codec()))
927    }
928
929    fn encode_null(&mut self, _tag: Tag, _: Identifier) -> Result<Self::Ok, Self::Error> {
930        Ok(())
931    }
932
933    fn encode_object_identifier(
934        &mut self,
935        tag: Tag,
936        oid: &[u32],
937        _: Identifier,
938    ) -> Result<Self::Ok, Self::Error> {
939        let mut encoder = crate::der::enc::Encoder::new(crate::der::enc::EncoderOptions::der());
940        let der = encoder.object_identifier_as_bytes(oid)?;
941        self.encode_octet_string(tag, Constraints::default(), &der, Identifier::EMPTY)
942    }
943
944    fn encode_octet_string(
945        &mut self,
946        tag: Tag,
947        constraints: Constraints,
948        value: &[u8],
949        _: Identifier,
950    ) -> Result<Self::Ok, Self::Error> {
951        let mut buffer = BitString::default();
952        self.encode_octet_string_into_buffer(constraints, value, &mut buffer)?;
953        self.extend(tag, &buffer);
954        Ok(())
955    }
956
957    fn encode_visible_string(
958        &mut self,
959        tag: Tag,
960        constraints: Constraints,
961        value: &types::VisibleString,
962        _: Identifier,
963    ) -> Result<Self::Ok, Self::Error> {
964        self.encode_known_multiplier_string(tag, &constraints, value)
965    }
966
967    fn encode_ia5_string(
968        &mut self,
969        tag: Tag,
970        constraints: Constraints,
971        value: &types::Ia5String,
972        _: Identifier,
973    ) -> Result<Self::Ok, Self::Error> {
974        self.encode_known_multiplier_string(tag, &constraints, value)
975    }
976
977    fn encode_general_string(
978        &mut self,
979        tag: Tag,
980        _: Constraints,
981        value: &types::GeneralString,
982        _: Identifier,
983    ) -> Result<Self::Ok, Self::Error> {
984        self.encode_octet_string(tag, Constraints::default(), value, Identifier::EMPTY)
985    }
986
987    fn encode_graphic_string(
988        &mut self,
989        tag: Tag,
990        _: Constraints,
991        value: &types::GraphicString,
992        _: Identifier,
993    ) -> Result<Self::Ok, Self::Error> {
994        self.encode_octet_string(tag, Constraints::default(), value, Identifier::EMPTY)
995    }
996
997    fn encode_printable_string(
998        &mut self,
999        tag: Tag,
1000        constraints: Constraints,
1001        value: &types::PrintableString,
1002        _: Identifier,
1003    ) -> Result<Self::Ok, Self::Error> {
1004        self.encode_known_multiplier_string(tag, &constraints, value)
1005    }
1006
1007    fn encode_numeric_string(
1008        &mut self,
1009        tag: Tag,
1010        constraints: Constraints,
1011        value: &types::NumericString,
1012        _: Identifier,
1013    ) -> Result<Self::Ok, Self::Error> {
1014        self.encode_known_multiplier_string(tag, &constraints, value)
1015    }
1016
1017    fn encode_teletex_string(
1018        &mut self,
1019        tag: Tag,
1020        constraints: Constraints,
1021        value: &types::TeletexString,
1022        _: Identifier,
1023    ) -> Result<Self::Ok, Self::Error> {
1024        self.encode_known_multiplier_string(tag, &constraints, value)
1025    }
1026
1027    fn encode_bmp_string(
1028        &mut self,
1029        tag: Tag,
1030        constraints: Constraints,
1031        value: &types::BmpString,
1032        _: Identifier,
1033    ) -> Result<Self::Ok, Self::Error> {
1034        self.encode_known_multiplier_string(tag, &constraints, value)
1035    }
1036
1037    fn encode_utf8_string(
1038        &mut self,
1039        tag: Tag,
1040        _: Constraints,
1041        value: &str,
1042        _: Identifier,
1043    ) -> Result<Self::Ok, Self::Error> {
1044        self.encode_octet_string(
1045            tag,
1046            Constraints::default(),
1047            value.as_bytes(),
1048            Identifier::EMPTY,
1049        )
1050    }
1051
1052    fn encode_utc_time(
1053        &mut self,
1054        tag: Tag,
1055        value: &types::UtcTime,
1056        _: Identifier,
1057    ) -> Result<Self::Ok, Self::Error> {
1058        self.encode_octet_string(
1059            tag,
1060            Constraints::default(),
1061            &crate::der::encode(value)?,
1062            Identifier::EMPTY,
1063        )
1064    }
1065
1066    fn encode_generalized_time(
1067        &mut self,
1068        tag: Tag,
1069        value: &types::GeneralizedTime,
1070        _: Identifier,
1071    ) -> Result<Self::Ok, Self::Error> {
1072        self.encode_octet_string(
1073            tag,
1074            Constraints::default(),
1075            &crate::der::encode(value)?,
1076            Identifier::EMPTY,
1077        )
1078    }
1079
1080    fn encode_date(
1081        &mut self,
1082        tag: Tag,
1083        value: &types::Date,
1084        _: Identifier,
1085    ) -> Result<Self::Ok, Self::Error> {
1086        self.encode_octet_string(
1087            tag,
1088            Constraints::default(),
1089            &crate::der::encode(value)?,
1090            Identifier::EMPTY,
1091        )
1092    }
1093
1094    fn encode_sequence_of<E: Encode>(
1095        &mut self,
1096        tag: Tag,
1097        values: &[E],
1098        constraints: Constraints,
1099        _: Identifier,
1100    ) -> Result<Self::Ok, Self::Error> {
1101        let mut buffer = BitString::default();
1102        let options = self.options;
1103
1104        self.encode_extensible_bit(&constraints, &mut buffer, || {
1105            constraints.size().is_some_and(|size_constraint| {
1106                size_constraint.extensible.is_some()
1107                    && size_constraint.constraint.contains(&values.len())
1108            })
1109        });
1110        let extension_bits = buffer.clone();
1111
1112        self.encode_length(&mut buffer, values.len(), constraints.size(), |range| {
1113            let mut buffer = BitString::default();
1114            let mut first_round = true;
1115            for value in &values[range] {
1116                let mut encoder = Self::new(options);
1117                if first_round {
1118                    encoder.parent_output_length = Some(extension_bits.len());
1119                    first_round = false;
1120                }
1121                E::encode(value, &mut encoder)?;
1122                buffer.extend(encoder.bitstring_output());
1123            }
1124            Ok(buffer)
1125        })?;
1126
1127        self.extend(tag, &buffer);
1128
1129        Ok(())
1130    }
1131
1132    fn encode_set_of<E: Encode + Eq + core::hash::Hash>(
1133        &mut self,
1134        tag: Tag,
1135        values: &types::SetOf<E>,
1136        constraints: Constraints,
1137        _: Identifier,
1138    ) -> Result<Self::Ok, Self::Error> {
1139        self.encode_sequence_of(tag, &values.to_vec(), constraints, Identifier::EMPTY)
1140    }
1141
1142    fn encode_explicit_prefix<V: Encode>(
1143        &mut self,
1144        tag: Tag,
1145        value: &V,
1146        _: Identifier,
1147    ) -> Result<Self::Ok, Self::Error> {
1148        if V::IS_CHOICE {
1149            value.encode(self)
1150        } else {
1151            value.encode_with_tag(self, tag)
1152        }
1153    }
1154
1155    fn encode_some<E: Encode>(
1156        &mut self,
1157        value: &E,
1158        _: Identifier,
1159    ) -> Result<Self::Ok, Self::Error> {
1160        self.set_presence(E::TAG, true);
1161        value.encode(self)
1162    }
1163
1164    fn encode_some_with_tag<E: Encode>(
1165        &mut self,
1166        tag: Tag,
1167        value: &E,
1168        _: Identifier,
1169    ) -> Result<Self::Ok, Self::Error> {
1170        self.set_presence(tag, true);
1171        value.encode_with_tag(self, tag)
1172    }
1173
1174    fn encode_some_with_tag_and_constraints<E: Encode>(
1175        &mut self,
1176        tag: Tag,
1177        constraints: Constraints,
1178        value: &E,
1179        _: Identifier,
1180    ) -> Result<Self::Ok, Self::Error> {
1181        self.set_presence(tag, true);
1182        value.encode_with_tag_and_constraints(self, tag, constraints, Identifier::EMPTY)
1183    }
1184
1185    fn encode_none<E: Encode>(&mut self, _: Identifier) -> Result<Self::Ok, Self::Error> {
1186        self.set_presence(E::TAG, false);
1187        Ok(())
1188    }
1189
1190    fn encode_none_with_tag(&mut self, tag: Tag, _: Identifier) -> Result<Self::Ok, Self::Error> {
1191        self.set_presence(tag, false);
1192        Ok(())
1193    }
1194
1195    fn encode_sequence<'b, const RL: usize, const EL: usize, C, F>(
1196        &'b mut self,
1197        tag: Tag,
1198        encoder_scope: F,
1199        _: Identifier,
1200    ) -> Result<Self::Ok, Self::Error>
1201    where
1202        C: crate::types::Constructed<RL, EL>,
1203        F: FnOnce(&mut Self::AnyEncoder<'b, RL, EL>) -> Result<(), Self::Error>,
1204    {
1205        let mut encoder = self.new_sequence_encoder::<RL, EL, C>();
1206        (encoder_scope)(&mut encoder)?;
1207        self.encode_constructed::<RL, EL, C>(tag, encoder)
1208    }
1209
1210    fn encode_set<'b, const RL: usize, const EL: usize, C, F>(
1211        &'b mut self,
1212        tag: Tag,
1213        encoder_scope: F,
1214        _: Identifier,
1215    ) -> Result<Self::Ok, Self::Error>
1216    where
1217        C: crate::types::Constructed<RL, EL>,
1218        F: FnOnce(&mut Self::AnyEncoder<'b, RL, EL>) -> Result<(), Self::Error>,
1219    {
1220        let mut set = self.new_set_encoder::<RL, EL, C>();
1221
1222        (encoder_scope)(&mut set)?;
1223
1224        self.encode_constructed::<RL, EL, C>(tag, set)
1225    }
1226
1227    fn encode_choice<E: Encode + crate::types::Choice>(
1228        &mut self,
1229        constraints: Constraints,
1230        tag: Tag,
1231        encode_fn: impl FnOnce(&mut Self) -> Result<Tag, Self::Error>,
1232        _: Identifier,
1233    ) -> Result<Self::Ok, Self::Error> {
1234        let mut buffer = BitString::new();
1235
1236        let is_root_extension = crate::types::TagTree::tag_contains(&tag, E::VARIANTS);
1237        self.encode_extensible_bit(&constraints, &mut buffer, || is_root_extension);
1238        let variants = crate::types::variants::Variants::from_static(if is_root_extension {
1239            E::VARIANTS
1240        } else {
1241            E::EXTENDED_VARIANTS.unwrap_or(&[])
1242        });
1243
1244        let index = variants
1245            .iter()
1246            .enumerate()
1247            .find_map(|(i, &variant_tag)| (tag == variant_tag).then_some(i))
1248            .ok_or_else(|| Error::variant_not_in_choice(self.codec()))?;
1249
1250        let bounds = if is_root_extension {
1251            let variance = variants.len();
1252            debug_assert!(variance > 0);
1253            if variance == 1 {
1254                None
1255            } else {
1256                Some(Some(variance))
1257            }
1258        } else {
1259            Some(None)
1260        };
1261
1262        let mut choice_encoder = Self::new(self.options.without_set_encoding());
1263        // Extensibility and index encoding size must be noted for byte alignment
1264        let mut choice_bits_len = 0;
1265        if E::EXTENDED_VARIANTS.is_some() && self.options.aligned {
1266            choice_bits_len += 1;
1267        }
1268        choice_bits_len += if let Some(Some(variance)) = bounds {
1269            crate::num::log2(variance as i128) as usize
1270        } else {
1271            0
1272        };
1273
1274        choice_encoder.parent_output_length = Some(choice_bits_len);
1275        let _tag = (encode_fn)(&mut choice_encoder)?;
1276
1277        match (index, bounds) {
1278            (index, Some(Some(_))) => {
1279                self.encode_integer_into_buffer::<usize>(
1280                    E::VARIANCE_CONSTRAINT,
1281                    &index,
1282                    &mut buffer,
1283                )?;
1284
1285                buffer.extend(choice_encoder.output);
1286            }
1287            (index, Some(None)) => {
1288                self.encode_normally_small_integer(index, &mut buffer)?;
1289                let mut output = choice_encoder.output();
1290
1291                if output.is_empty() {
1292                    output.push(0);
1293                }
1294                self.encode_octet_string_into_buffer(Constraints::default(), &output, &mut buffer)?;
1295            }
1296            (_, None) => {
1297                buffer.extend(choice_encoder.output);
1298            }
1299        }
1300
1301        self.extend(tag, &buffer);
1302        Ok(())
1303    }
1304
1305    fn encode_extension_addition<E: Encode>(
1306        &mut self,
1307        tag: Tag,
1308        constraints: Constraints,
1309        value: E,
1310        _: Identifier,
1311    ) -> Result<Self::Ok, Self::Error> {
1312        let mut encoder = Self::new(self.options.without_set_encoding());
1313        if value.is_present() {
1314            E::encode_with_tag_and_constraints(
1315                &value,
1316                &mut encoder,
1317                tag,
1318                constraints,
1319                Identifier::EMPTY,
1320            )?;
1321            self.extension_fields[self.extension_bitfield.0] = Some(encoder.output());
1322            self.set_extension_presence(true);
1323        } else {
1324            self.extension_fields[self.extension_bitfield.0] = None;
1325            self.set_extension_presence(false);
1326        }
1327        Ok(())
1328    }
1329
1330    fn encode_extension_addition_group<const RL: usize, const EL: usize, E>(
1331        &mut self,
1332        value: Option<&E>,
1333        _: Identifier,
1334    ) -> Result<Self::Ok, Self::Error>
1335    where
1336        E: Encode + crate::types::Constructed<RL, EL>,
1337    {
1338        let Some(value) = value else {
1339            self.extension_fields[self.extension_bitfield.0] = None;
1340            self.set_extension_presence(false);
1341            return Ok(());
1342        };
1343        let mut encoder = self.new_sequence_encoder::<RL, EL, E>();
1344        encoder.is_extension_sequence = true;
1345        encoder.number_optional_default_fields = E::FIELDS.number_of_optional_and_default_fields();
1346        value.encode(&mut encoder)?;
1347        let out = encoder.output();
1348
1349        let all_absent = if E::FIELDS.has_required_field() {
1350            false
1351        } else if encoder.root_bitfield.0 > 0 {
1352            encoder.root_bitfield.1[..encoder.root_bitfield.0]
1353                .iter()
1354                .all(|(present, _)| !present)
1355        } else {
1356            out.iter().all(|&b| b == 0)
1357        };
1358
1359        if all_absent {
1360            self.extension_fields[self.extension_bitfield.0] = None;
1361            self.set_extension_presence(false);
1362        } else {
1363            self.extension_fields[self.extension_bitfield.0] = Some(out);
1364            self.set_extension_presence(true);
1365        }
1366        Ok(())
1367    }
1368}
1369
1370#[derive(Debug)]
1371enum Input<'input> {
1372    Bit(bool),
1373    Byte(u8),
1374    Bits(&'input BitString),
1375    Bytes(&'input [u8]),
1376}
1377
1378impl<'input> From<&'input BitString> for Input<'input> {
1379    fn from(value: &'input BitString) -> Self {
1380        Self::Bits(value)
1381    }
1382}
1383
1384impl<'input> From<&'input [u8]> for Input<'input> {
1385    fn from(value: &'input [u8]) -> Self {
1386        Self::Bytes(value)
1387    }
1388}
1389
1390impl<'input> From<&'input Vec<u8>> for Input<'input> {
1391    fn from(value: &'input Vec<u8>) -> Self {
1392        Self::Bytes(value)
1393    }
1394}
1395
1396impl From<bool> for Input<'_> {
1397    fn from(value: bool) -> Self {
1398        Self::Bit(value)
1399    }
1400}
1401
1402impl From<u8> for Input<'_> {
1403    fn from(value: u8) -> Self {
1404        Self::Byte(value)
1405    }
1406}
1407
1408#[cfg(test)]
1409mod tests {
1410    use super::*;
1411
1412    use crate::Encoder as _;
1413
1414    #[derive(crate::AsnType, Default, crate::Encode, Clone, Copy)]
1415    #[rasn(crate_root = "crate")]
1416    struct Byte {
1417        one: bool,
1418        two: bool,
1419        three: bool,
1420        four: bool,
1421        five: bool,
1422        six: bool,
1423        seven: bool,
1424        eight: bool,
1425    }
1426
1427    impl Byte {
1428        const MAX: Self = Self {
1429            one: true,
1430            two: true,
1431            three: true,
1432            four: true,
1433            five: true,
1434            six: true,
1435            seven: true,
1436            eight: true,
1437        };
1438    }
1439
1440    #[test]
1441    fn length() {
1442        let encoder = Encoder::<0, 0>::new(EncoderOptions::unaligned());
1443        let mut buffer = types::BitString::new();
1444        encoder
1445            .encode_length(
1446                &mut buffer,
1447                4,
1448                Some(&Extensible::new(constraints::Size::new(
1449                    constraints::Bounded::new(1, 64),
1450                ))),
1451                |_| Ok(<_>::default()),
1452            )
1453            .unwrap();
1454        assert_eq!(&[0xC], buffer.as_raw_slice());
1455    }
1456
1457    #[test]
1458    fn sequence() {
1459        assert_eq!(&[0xff], &*crate::uper::encode(&Byte::MAX).unwrap());
1460    }
1461
1462    #[test]
1463    fn constrained_integer() {
1464        assert_eq!(&[0xff], &*crate::uper::encode(&0xffu8).unwrap());
1465    }
1466
1467    #[test]
1468    fn normally_small_integer() {
1469        let mut encoder = Encoder::<0, 0>::new(EncoderOptions::unaligned());
1470        let mut buffer = types::BitString::new();
1471        encoder
1472            .encode_normally_small_integer(2, &mut buffer)
1473            .unwrap();
1474        assert_eq!(buffer.len(), 7);
1475        assert_eq!(bitvec::bits![0, 0, 0, 0, 0, 1, 0], buffer);
1476    }
1477
1478    #[test]
1479    fn unconstrained_integer() {
1480        assert_eq!(
1481            &[0b00000010, 0b00010000, 0],
1482            &*crate::uper::encode(&types::Integer::from(4096)).unwrap()
1483        );
1484        struct CustomInt(i32);
1485
1486        impl crate::AsnType for CustomInt {
1487            const TAG: Tag = Tag::INTEGER;
1488            const CONSTRAINTS: Constraints = constraints!(value_constraint!(end: 65535));
1489        }
1490
1491        impl crate::Encode for CustomInt {
1492            fn encode_with_tag_and_constraints<'b, E: crate::Encoder<'b>>(
1493                &self,
1494                encoder: &mut E,
1495                tag: Tag,
1496                constraints: Constraints,
1497                _: Identifier,
1498            ) -> Result<(), E::Error> {
1499                encoder
1500                    .encode_integer::<i128>(tag, constraints, &self.0.into(), Identifier::EMPTY)
1501                    .map(drop)
1502            }
1503        }
1504
1505        assert_eq!(
1506            &[0b00000001, 0b01111111],
1507            &*crate::uper::encode(&CustomInt(127)).unwrap()
1508        );
1509        assert_eq!(
1510            &[0b00000001, 0b10000000],
1511            &*crate::uper::encode(&CustomInt(-128)).unwrap()
1512        );
1513        assert_eq!(
1514            &[0b00000010, 0b00000000, 0b10000000],
1515            &*crate::uper::encode(&CustomInt(128)).unwrap()
1516        );
1517    }
1518
1519    #[test]
1520    fn semi_constrained_integer() {
1521        let mut encoder = Encoder::<0, 0>::new(EncoderOptions::unaligned());
1522        const CONSTRAINT_1: Constraints = constraints!(value_constraint!(start: -1));
1523        encoder
1524            .encode_integer::<i128>(Tag::INTEGER, CONSTRAINT_1, &4096.into(), Identifier::EMPTY)
1525            .unwrap();
1526
1527        assert_eq!(&[2, 0b00010000, 1], &*encoder.output.clone().into_vec());
1528        encoder.output.clear();
1529        const CONSTRAINT_2: Constraints = constraints!(value_constraint!(start: 1));
1530        encoder
1531            .encode_integer::<i128>(Tag::INTEGER, CONSTRAINT_2, &127.into(), Identifier::EMPTY)
1532            .unwrap();
1533        assert_eq!(&[1, 0b01111110], &*encoder.output.clone().into_vec());
1534        encoder.output.clear();
1535        const CONSTRAINT_3: Constraints = constraints!(value_constraint!(start: 0));
1536        encoder
1537            .encode_integer::<i128>(Tag::INTEGER, CONSTRAINT_3, &128.into(), Identifier::EMPTY)
1538            .unwrap();
1539        assert_eq!(&[1, 0b10000000], &*encoder.output.into_vec());
1540    }
1541
1542    #[track_caller]
1543    fn assert_encode<T: Encode>(options: EncoderOptions, value: T, expected: &[u8]) {
1544        let mut encoder = Encoder::<0, 0>::new(options);
1545        T::encode(&value, &mut encoder).unwrap();
1546        let output = encoder.output.clone().into_vec();
1547        assert_eq!(
1548            expected
1549                .iter()
1550                .map(|ch| format!("{ch:08b}"))
1551                .collect::<Vec<_>>(),
1552            output
1553                .iter()
1554                .map(|ch| format!("{ch:08b}"))
1555                .collect::<Vec<_>>()
1556        );
1557    }
1558
1559    #[test]
1560    fn visible_string() {
1561        use crate::types::VisibleString;
1562
1563        assert_encode(
1564            EncoderOptions::unaligned(),
1565            VisibleString::try_from("John").unwrap(),
1566            &[4, 0x95, 0xBF, 0x46, 0xE0],
1567        );
1568        assert_encode(
1569            EncoderOptions::aligned(),
1570            VisibleString::try_from("John").unwrap(),
1571            &[4, 0x4A, 0x6F, 0x68, 0x6E],
1572        );
1573    }
1574
1575    #[test]
1576    fn constrained_visible_string() {
1577        use crate::{AsnType, types::VisibleString};
1578
1579        #[derive(AsnType, Encode, Clone, PartialEq)]
1580        #[rasn(delegate, size("1..=3", extensible))]
1581        #[rasn(crate_root = "crate")]
1582        struct ExtSizeRangeString(pub VisibleString);
1583
1584        // Extensible VisibleString with size range constraint
1585        assert_encode(
1586            EncoderOptions::unaligned(),
1587            ExtSizeRangeString(VisibleString::try_from("abc").unwrap()),
1588            &[88, 113, 99],
1589        );
1590        assert_encode(
1591            EncoderOptions::aligned(),
1592            ExtSizeRangeString(VisibleString::try_from("abc").unwrap()),
1593            &[64, 97, 98, 99],
1594        );
1595        assert_encode(
1596            EncoderOptions::unaligned(),
1597            ExtSizeRangeString(VisibleString::try_from("abcd").unwrap()),
1598            &[130, 97, 197, 143, 32],
1599        );
1600        assert_encode(
1601            EncoderOptions::aligned(),
1602            ExtSizeRangeString(VisibleString::try_from("abcd").unwrap()),
1603            &[128, 4, 97, 98, 99, 100],
1604        );
1605    }
1606
1607    #[test]
1608    fn constrained_bit_string() {
1609        use crate::AsnType;
1610
1611        #[derive(AsnType, Encode, Clone, PartialEq)]
1612        #[rasn(delegate, size("1..=4", extensible))]
1613        #[rasn(crate_root = "crate")]
1614        struct ExtSizeRangeBitStr(pub BitString);
1615
1616        #[derive(AsnType, Encode, Clone, PartialEq)]
1617        #[rasn(delegate, size("2", extensible))]
1618        #[rasn(crate_root = "crate")]
1619        struct ExtStrictSizeBitStr(pub BitString);
1620
1621        // Extensible BIT STRING with size range constraint
1622        assert_encode(
1623            EncoderOptions::unaligned(),
1624            ExtSizeRangeBitStr(BitString::from_iter([true].iter())),
1625            &[16],
1626        );
1627        assert_encode(
1628            EncoderOptions::aligned(),
1629            ExtSizeRangeBitStr(BitString::from_iter([true].iter())),
1630            &[0, 128],
1631        );
1632        assert_encode(
1633            EncoderOptions::unaligned(),
1634            ExtSizeRangeBitStr(BitString::from_iter(
1635                [true, false, true, false, true, true].iter(),
1636            )),
1637            &[131, 86],
1638        );
1639        assert_encode(
1640            EncoderOptions::aligned(),
1641            ExtSizeRangeBitStr(BitString::from_iter(
1642                [true, false, true, false, true, true].iter(),
1643            )),
1644            &[128, 6, 172],
1645        );
1646        // Edge case ITU-T X.691 (02/2021) ยง16 Note: strictly sized BIT STRINGs shorter than 17 bits
1647        assert_encode(
1648            EncoderOptions::unaligned(),
1649            ExtStrictSizeBitStr(BitString::from_iter([true, true].iter())),
1650            &[96],
1651        );
1652        assert_encode(
1653            EncoderOptions::aligned(),
1654            ExtStrictSizeBitStr(BitString::from_iter([true, true].iter())),
1655            &[96],
1656        );
1657        assert_encode(
1658            EncoderOptions::unaligned(),
1659            ExtStrictSizeBitStr(BitString::from_iter([true, true, true].iter())),
1660            &[129, 240],
1661        );
1662        assert_encode(
1663            EncoderOptions::aligned(),
1664            ExtStrictSizeBitStr(BitString::from_iter([true, true, true].iter())),
1665            &[128, 3, 224],
1666        );
1667    }
1668
1669    #[test]
1670    fn constrained_octet_string() {
1671        use crate::{AsnType, types::OctetString};
1672
1673        #[derive(AsnType, Encode, Clone, PartialEq)]
1674        #[rasn(delegate, size("1..=3", extensible))]
1675        #[rasn(crate_root = "crate")]
1676        struct ExtSizeRangeOctetStr(pub OctetString);
1677
1678        // Extensible OCTET STRING with size range constraint
1679        assert_encode(
1680            EncoderOptions::unaligned(),
1681            ExtSizeRangeOctetStr(OctetString::from_static(&[1, 2])),
1682            &[32, 32, 64],
1683        );
1684        assert_encode(
1685            EncoderOptions::aligned(),
1686            ExtSizeRangeOctetStr(OctetString::from_static(&[1, 2])),
1687            &[32, 1, 2],
1688        );
1689        assert_encode(
1690            EncoderOptions::unaligned(),
1691            ExtSizeRangeOctetStr(OctetString::from_static(&[1, 2, 3, 4])),
1692            &[130, 0, 129, 1, 130, 0],
1693        );
1694        assert_encode(
1695            EncoderOptions::aligned(),
1696            ExtSizeRangeOctetStr(OctetString::from_static(&[1, 2, 3, 4])),
1697            &[128, 4, 1, 2, 3, 4],
1698        );
1699    }
1700
1701    #[test]
1702    fn sequence_of() {
1703        let make_buffer =
1704            |length| crate::uper::encode(&alloc::vec![Byte::default(); length]).unwrap();
1705        assert_eq!(&[5, 0, 0, 0, 0, 0], &*(make_buffer)(5));
1706        assert!((make_buffer)(130).starts_with(&[0b10000000u8, 0b10000010]));
1707        assert!((make_buffer)(16000).starts_with(&[0b10111110u8, 0b10000000]));
1708        let buffer = (make_buffer)(THIRTY_TWO_K as usize);
1709        assert_eq!(THIRTY_TWO_K as usize + 2, buffer.len());
1710        assert!(buffer.starts_with(&[0b11000010]));
1711        assert!(buffer.ends_with(&[0]));
1712        let buffer = (make_buffer)(99000);
1713        assert_eq!(99000 + 4, buffer.len());
1714        assert!(buffer.starts_with(&[0b11000100]));
1715        assert!(buffer[1 + SIXTY_FOUR_K as usize..].starts_with(&[0b11000010]));
1716        assert!(
1717            buffer[SIXTY_FOUR_K as usize + THIRTY_TWO_K as usize + 2..]
1718                .starts_with(&[0b10000010, 0b10111000])
1719        );
1720    }
1721}