rasn/per/
enc.rs

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