asn1rs/syn/io/
uper.rs

1use crate::io::per::err::Error;
2use crate::io::per::err::ErrorKind;
3use crate::io::per::unaligned::buffer::BitBuffer;
4use crate::io::per::unaligned::BitWrite;
5use crate::io::per::unaligned::BYTE_LEN;
6use crate::io::per::PackedRead;
7use crate::io::per::PackedWrite;
8use crate::model::Charset;
9use crate::syn::*;
10use std::fmt::Debug;
11use std::ops::Range;
12
13pub use crate::io::per::unaligned::buffer::Bits;
14pub use crate::io::per::unaligned::ScopedBitRead;
15
16#[derive(Debug, Clone)]
17pub enum Scope {
18    OptBitField(Range<usize>),
19    AllBitField(Range<usize>),
20    /// According to ITU-T X.691 | ISO/IEC 8825-2:2015, an extensible struct is built as
21    ///  - part1
22    ///    - `eo`: flag for whether the struct serializes/has payload with extended fields
23    ///    - flags for optional fields (only for the non-extended fields!)
24    ///    - fields serialized 'inline' (only for the non-extended fields!)
25    ///  - part2
26    ///    - `eo`: number of extended fields (as normally-small-int)
27    ///    - `eo`: presence-flag for each extended field (only OPTIONAL fields seem to
28    ///            influence these flags!?)
29    ///    - `eo`: fields serialized as
30    ///      - length-determinant
31    ///      - sub-buffer with actual content
32    ///
33    /// `eo` for `extensible only` attributes
34    ///
35    /// To find the beginning of part2 - and thus to be able to insert the secondary-header - one
36    /// needs to keep track of the current field number. Also, the position of where to write
37    /// the presence flags to must be updated as well.
38    ExtensibleSequence {
39        name: &'static str,
40        bit_pos: usize,
41        opt_bit_field: Option<Range<usize>>,
42        calls_until_ext_bitfield: usize,
43        number_of_ext_fields: usize,
44    },
45    /// Indicates that the extensible sequence has no extension body
46    ExtensibleSequenceEmpty(&'static str),
47}
48
49impl Scope {
50    #[inline]
51    pub const fn exhausted(&self) -> bool {
52        match self {
53            Scope::OptBitField(range) => range.start == range.end,
54            Scope::AllBitField(range) => range.start == range.end,
55            Scope::ExtensibleSequence {
56                name: _,
57                bit_pos: _,
58                opt_bit_field,
59                calls_until_ext_bitfield: _,
60                number_of_ext_fields: _,
61            } => match opt_bit_field {
62                Some(range) => range.start == range.end,
63                None => true,
64            },
65            Scope::ExtensibleSequenceEmpty(_) => true,
66        }
67    }
68
69    #[inline]
70    pub const fn encode_as_open_type_field(&self) -> bool {
71        matches!(
72            self,
73            Scope::AllBitField(_) | Scope::ExtensibleSequenceEmpty(_)
74        )
75    }
76
77    #[inline]
78    pub fn write_into_field(
79        &mut self,
80        buffer: &mut BitBuffer,
81        is_opt: bool,
82        is_present: bool,
83    ) -> Result<(), Error> {
84        match self {
85            Scope::OptBitField(range) => {
86                if is_opt {
87                    let result =
88                        buffer.with_write_position_at(range.start, |b| b.write_bit(is_present));
89                    range.start += 1;
90                    result
91                } else {
92                    Ok(())
93                }
94            }
95            Scope::AllBitField(range) => {
96                let result =
97                    buffer.with_write_position_at(range.start, |b| b.write_bit(is_present));
98                range.start += 1;
99                result
100            }
101            Scope::ExtensibleSequence {
102                name,
103                bit_pos: ext_bit_pos,
104                opt_bit_field,
105                calls_until_ext_bitfield,
106                number_of_ext_fields,
107            } => {
108                if *calls_until_ext_bitfield == 0 {
109                    buffer.with_write_position_at(*ext_bit_pos, |b| b.write_bit(is_present))?;
110                    if is_present {
111                        // when we reach this point, there is never zero numbers of ext-fields
112                        buffer.write_normally_small_non_negative_whole_number(
113                            *number_of_ext_fields as u64 - 1,
114                        )?;
115                        let pos = buffer.write_position;
116                        for _ in 0..*number_of_ext_fields {
117                            if let Err(e) = buffer.write_bit(true) {
118                                buffer.write_position = pos;
119                                return Err(e);
120                            }
121                        }
122
123                        // pos + 1 because the bit for the current call is already set
124                        // by the initializer loop above
125                        let range = pos + 1..buffer.write_position;
126                        *self = Scope::AllBitField(range);
127                    } else {
128                        *self = Scope::ExtensibleSequenceEmpty(name);
129                    }
130                    // no need for this
131                    // if is_present is true, the bit is already set (initialize loop above)
132                    // if is_present is false, no bit will be written (empty)
133                    // self.write_into_field(buffer, is_opt, is_present)
134                    Ok(())
135                } else {
136                    *calls_until_ext_bitfield = calls_until_ext_bitfield.saturating_sub(1);
137                    if let Some(range) = opt_bit_field {
138                        if is_opt {
139                            let result = buffer
140                                .with_write_position_at(range.start, |b| b.write_bit(is_present));
141                            range.start += 1;
142                            result
143                        } else {
144                            Ok(())
145                        }
146                    } else {
147                        Ok(())
148                    }
149                }
150            }
151            Scope::ExtensibleSequenceEmpty(name) => {
152                if is_present {
153                    Err(ErrorKind::ExtensionFieldsInconsistent(name.to_string()).into())
154                } else {
155                    Ok(())
156                }
157            }
158        }
159    }
160
161    #[inline]
162    pub fn read_from_field(
163        &mut self,
164        #[cfg(feature = "descriptive-deserialize-errors")] descriptions: &mut Vec<ScopeDescription>,
165        bits: &mut impl ScopedBitRead,
166        is_opt: bool,
167    ) -> Result<Option<bool>, Error> {
168        match self {
169            Scope::OptBitField(range) => {
170                if range.start >= range.end {
171                    Ok(Some(false))
172                } else if is_opt {
173                    let result =
174                        bits.with_read_position_at(range.start, |buffer| buffer.read_bit());
175                    range.start += 1;
176                    Some(result).transpose()
177                } else {
178                    Ok(None)
179                }
180            }
181            Scope::AllBitField(range) => {
182                if range.start < range.end {
183                    let result =
184                        bits.with_read_position_at(range.start, |buffer| buffer.read_bit());
185                    range.start += 1;
186                    Some(result).transpose()
187                } else {
188                    // all further extensible fields are not present
189                    Ok(Some(false))
190                }
191            }
192            Scope::ExtensibleSequence {
193                name,
194                bit_pos: ext_bit_pos,
195                opt_bit_field,
196                calls_until_ext_bitfield,
197                number_of_ext_fields,
198            } => {
199                if *calls_until_ext_bitfield == 0 {
200                    if bits.with_read_position_at(*ext_bit_pos, |b| b.read_bit())? {
201                        let read_number_of_ext_fields =
202                            bits.read_normally_small_length()? as usize + 1;
203                        if read_number_of_ext_fields > *number_of_ext_fields {
204                            #[cfg(feature = "descriptive-deserialize-errors")]
205                            descriptions.push(ScopeDescription::warning(
206                                format!("read_number_of_ext_fields({read_number_of_ext_fields}) > *number_of_ext_fields({number_of_ext_fields})")
207                            ));
208                            //     return Err(Error::UnsupportedOperation(format!(
209                            //         "Expected no more than {} extended field{} but got {}",
210                            //         number_of_ext_fields,
211                            //         if *number_of_ext_fields != 1 { "s" } else { "" },
212                            //         read_number_of_ext_fields
213                            //     )));
214                        }
215                        let range = bits.pos()..bits.pos() + *number_of_ext_fields;
216                        bits.set_pos(range.start + read_number_of_ext_fields); // skip bit-field
217                        *self = Scope::AllBitField(range);
218                    } else {
219                        *self = Scope::ExtensibleSequenceEmpty(name);
220                    }
221                    self.read_from_field(
222                        #[cfg(feature = "descriptive-deserialize-errors")]
223                        descriptions,
224                        bits,
225                        is_opt,
226                    )
227                } else {
228                    *calls_until_ext_bitfield = calls_until_ext_bitfield.saturating_sub(1);
229                    opt_bit_field
230                        .as_mut()
231                        .filter(|_| is_opt)
232                        .map(|range| {
233                            let result =
234                                bits.with_read_position_at(range.start, |buffer| buffer.read_bit());
235                            range.start += 1;
236                            result
237                        })
238                        .transpose()
239                }
240            }
241            Scope::ExtensibleSequenceEmpty(_) => Ok(Some(false)),
242        }
243    }
244}
245
246#[derive(Default)]
247pub struct UperWriter {
248    bits: BitBuffer,
249    scope: Option<Scope>,
250}
251
252impl UperWriter {
253    pub fn with_capacity(capacity_bytes: usize) -> Self {
254        Self {
255            bits: BitBuffer::with_capacity(capacity_bytes),
256            ..Default::default()
257        }
258    }
259
260    pub fn byte_content(&self) -> &[u8] {
261        self.bits.content()
262    }
263
264    pub const fn bit_len(&self) -> usize {
265        self.bits.bit_len()
266    }
267
268    pub fn into_bytes_vec(self) -> Vec<u8> {
269        debug_assert_eq!(
270            (self.bit_len() + BYTE_LEN - 1) / BYTE_LEN,
271            self.bits.buffer.len()
272        );
273        self.bits.into()
274    }
275
276    pub fn as_reader(&self) -> UperReader<Bits> {
277        UperReader::from(Bits::from((self.byte_content(), self.bit_len())))
278    }
279
280    #[inline]
281    pub fn scope_pushed<T, E, F: FnOnce(&mut Self) -> Result<T, E>>(
282        &mut self,
283        scope: Scope,
284        f: F,
285    ) -> Result<T, E> {
286        let original = core::mem::replace(&mut self.scope, Some(scope));
287        let result = f(self);
288        if cfg!(debug_assertions) && result.is_ok() {
289            let scope = core::mem::replace(&mut self.scope, original);
290            // call to .unwrap() is save because this is supposed to be the original from above
291            debug_assert!(
292                scope.clone().unwrap().exhausted(),
293                "Not exhausted: {:?}",
294                scope.unwrap()
295            );
296        } else {
297            self.scope = original;
298        }
299        result
300    }
301
302    #[inline]
303    pub fn scope_stashed<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
304        let scope = self.scope.take();
305        let result = f(self);
306        self.scope = scope;
307        result
308    }
309
310    #[inline]
311    pub fn write_bit_field_entry(&mut self, is_opt: bool, is_present: bool) -> Result<(), Error> {
312        if let Some(scope) = &mut self.scope {
313            scope.write_into_field(&mut self.bits, is_opt, is_present)
314        } else if is_opt {
315            self.bits.write_bit(is_present)
316        } else {
317            Ok(())
318        }
319    }
320
321    #[inline]
322    #[allow(clippy::redundant_pattern_matching)] // allow for const_*!
323    pub fn with_buffer<T, F: FnOnce(&mut Self) -> Result<T, Error>>(
324        &mut self,
325        f: F,
326    ) -> Result<T, Error> {
327        if const_map_or!(self.scope, Scope::encode_as_open_type_field, false) {
328            let mut writer = UperWriter::with_capacity(512);
329            let result = f(&mut writer)?;
330            self.bits
331                .write_octetstring(None, None, false, writer.bits.content())?;
332            Ok(result)
333        } else {
334            f(self)
335        }
336    }
337
338    #[inline]
339    pub fn write_extensible_bit_and_length_or_err(
340        &mut self,
341        extensible: bool,
342        min: Option<u64>,
343        max: Option<u64>,
344        upper_limit: u64,
345        len: u64,
346    ) -> Result<bool, Error> {
347        let unwrapped_min = const_unwrap_or!(min, 0);
348        let unwrapped_max = const_unwrap_or!(max, upper_limit);
349        let out_of_range = len < unwrapped_min || len > unwrapped_max;
350
351        if extensible {
352            self.bits.write_bit(out_of_range)?;
353        }
354
355        if out_of_range {
356            if !extensible {
357                return Err(ErrorKind::SizeNotInRange(len, unwrapped_min, unwrapped_max).into());
358            } else {
359                self.bits.write_length_determinant(None, None, len)?;
360            }
361        } else {
362            self.bits.write_length_determinant(min, max, len)?;
363        }
364
365        Ok(out_of_range)
366    }
367}
368
369impl Writer for UperWriter {
370    type Error = Error;
371
372    #[inline]
373    fn write_sequence<C: sequence::Constraint, F: Fn(&mut Self) -> Result<(), Self::Error>>(
374        &mut self,
375        f: F,
376    ) -> Result<(), Self::Error> {
377        self.write_bit_field_entry(false, true)?;
378        self.with_buffer(|w| {
379            let extension = if let Some(extension_after) = C::EXTENDED_AFTER_FIELD {
380                let bit_pos = w.bits.write_position;
381                // if no extension field is present, none will call into overwriting this
382                w.bits.write_bit(false)?;
383                Some((extension_after, bit_pos))
384            } else {
385                None
386            };
387
388            // In UPER the values for all OPTIONAL flags are written before any field
389            // value is written. This remembers their position, so a later call of `write_opt`
390            // can write them to the buffer
391            let write_pos = w.bits.write_position;
392            let range = write_pos..write_pos + C::STD_OPTIONAL_FIELDS as usize;
393            for _ in 0..C::STD_OPTIONAL_FIELDS {
394                // insert in reverse order so that a simple pop() in `write_opt` retrieves
395                // the relevant position
396                if let Err(e) = w.bits.write_bit(false) {
397                    w.bits.write_position = write_pos; // undo write_bits
398                    return Err(e);
399                }
400            }
401
402            if let Some((extension_after, bit_pos)) = extension {
403                w.scope_pushed(
404                    Scope::ExtensibleSequence {
405                        name: C::NAME,
406                        bit_pos,
407                        opt_bit_field: Some(range),
408                        calls_until_ext_bitfield: (extension_after + 1) as usize,
409                        number_of_ext_fields: (C::FIELD_COUNT - (extension_after + 1)) as usize,
410                    },
411                    f,
412                )
413            } else {
414                w.scope_pushed(Scope::OptBitField(range), f)
415            }
416        })
417    }
418
419    #[inline]
420    #[allow(clippy::redundant_pattern_matching)] // allow for const_*!
421    fn write_sequence_of<C: sequenceof::Constraint, T: WritableType>(
422        &mut self,
423        slice: &[T::Type],
424    ) -> Result<(), Self::Error> {
425        self.write_bit_field_entry(false, true)?;
426        self.scope_stashed(|w| {
427            w.write_extensible_bit_and_length_or_err(
428                C::EXTENSIBLE,
429                C::MIN,
430                C::MAX,
431                i64::MAX as u64,
432                slice.len() as u64,
433            )?;
434
435            w.scope_stashed(|w| {
436                for value in slice {
437                    T::write_value(w, value)?;
438                }
439                Ok(())
440            })
441        })
442    }
443
444    #[inline]
445    fn write_set<C: set::Constraint, F: Fn(&mut Self) -> Result<(), Self::Error>>(
446        &mut self,
447        f: F,
448    ) -> Result<(), Self::Error> {
449        self.write_sequence::<C, F>(f)
450    }
451
452    #[inline]
453    fn write_set_of<C: setof::Constraint, T: WritableType>(
454        &mut self,
455        slice: &[<T as WritableType>::Type],
456    ) -> Result<(), Self::Error> {
457        self.write_sequence_of::<C, T>(slice)
458    }
459
460    #[inline]
461    fn write_enumerated<C: enumerated::Constraint>(
462        &mut self,
463        enumerated: &C,
464    ) -> Result<(), Self::Error> {
465        self.write_bit_field_entry(false, true)?;
466        self.with_buffer(|w| {
467            w.bits.write_enumeration_index(
468                C::STD_VARIANT_COUNT,
469                C::EXTENSIBLE,
470                enumerated.to_choice_index(),
471            )
472        })
473    }
474
475    #[inline]
476    fn write_choice<C: choice::Constraint>(&mut self, choice: &C) -> Result<(), Self::Error> {
477        self.write_bit_field_entry(false, true)?;
478        self.scope_stashed(|w| {
479            let index = choice.to_choice_index();
480
481            // this fails if the index is out of range
482            w.bits
483                .write_choice_index(C::STD_VARIANT_COUNT, C::EXTENSIBLE, index)?;
484
485            if index >= C::STD_VARIANT_COUNT {
486                // TODO performance
487                let mut writer = UperWriter::with_capacity(512);
488                choice.write_content(&mut writer)?;
489                w.bits
490                    .write_octetstring(None, None, false, writer.byte_content())
491            } else {
492                choice.write_content(w)
493            }
494        })
495    }
496
497    #[inline]
498    #[allow(clippy::redundant_pattern_matching)] // allow for const_*!
499    fn write_opt<T: WritableType>(
500        &mut self,
501        value: Option<&<T as WritableType>::Type>,
502    ) -> Result<(), Self::Error> {
503        self.write_bit_field_entry(true, const_is_some!(value))?;
504        if let Some(value) = value {
505            self.with_buffer(|w| w.scope_stashed(|w| T::write_value(w, value)))
506        } else {
507            Ok(())
508        }
509    }
510
511    #[inline]
512    fn write_default<C: default::Constraint<Owned = T::Type>, T: WritableType>(
513        &mut self,
514        value: &T::Type,
515    ) -> Result<(), Self::Error> {
516        let present = C::DEFAULT_VALUE.ne(value);
517        self.write_bit_field_entry(true, present)?;
518        if present {
519            self.scope_stashed(|w| T::write_value(w, value))
520        } else {
521            Ok(())
522        }
523    }
524
525    #[inline]
526    #[allow(clippy::redundant_pattern_matching)] // allow for const_*!
527    fn write_number<T: numbers::Number, C: numbers::Constraint<T>>(
528        &mut self,
529        value: T,
530    ) -> Result<(), Self::Error> {
531        self.write_bit_field_entry(false, true)?;
532        let value = value.to_i64();
533
534        let max_fn = if C::EXTENSIBLE {
535            let min = const_unwrap_or!(C::MIN, 0);
536            let max = const_unwrap_or!(C::MAX, i64::MAX);
537            value < min || value > max
538        } else {
539            const_is_none!(C::MIN) && const_is_none!(C::MAX)
540        };
541
542        if max_fn {
543            self.with_buffer(|w| {
544                if C::EXTENSIBLE {
545                    w.bits.write_bit(true)?;
546                }
547                w.bits.write_unconstrained_whole_number(value)
548            })
549        } else {
550            self.with_buffer(|w| {
551                if C::EXTENSIBLE {
552                    w.bits.write_bit(false)?;
553                }
554                w.bits.write_constrained_whole_number(
555                    const_unwrap_or!(C::MIN, 0),
556                    const_unwrap_or!(C::MAX, i64::MAX),
557                    value,
558                )
559            })
560        }
561    }
562
563    #[inline]
564    #[allow(clippy::redundant_pattern_matching)] // allow for const_*!
565    fn write_utf8string<C: utf8string::Constraint>(
566        &mut self,
567        value: &str,
568    ) -> Result<(), Self::Error> {
569        self.write_bit_field_entry(false, true)?;
570        self.with_buffer(|w| {
571            if !C::EXTENSIBLE {
572                let chars = value.chars().count() as u64;
573                let min = const_unwrap_or!(C::MIN, 0);
574                let max = const_unwrap_or!(C::MAX, u64::MAX);
575                if chars < min || chars > max {
576                    return Err(ErrorKind::SizeNotInRange(chars, min, max).into());
577                }
578            }
579
580            // ITU-T X.691 | ISO/IEC 8825-2:2015, chapter 30.3
581            // For 'known-multiplier character string types' there is no min/max in the encoding
582            w.bits
583                .write_octetstring(None, None, false, value.as_bytes())
584        })
585    }
586
587    #[inline]
588    fn write_ia5string<C: ia5string::Constraint>(
589        &mut self,
590        value: &str,
591    ) -> Result<(), Self::Error> {
592        self.write_bit_field_entry(false, true)?;
593        self.with_buffer(|w| {
594            Error::ensure_string_valid(Charset::Ia5, value)?;
595
596            w.write_extensible_bit_and_length_or_err(
597                C::EXTENSIBLE,
598                C::MIN,
599                C::MAX,
600                u64::MAX,
601                value.chars().count() as u64,
602            )?;
603
604            for char in value.chars().map(|c| c as u8) {
605                // 7 bits
606                w.bits.write_bits_with_offset(&[char], 1)?;
607            }
608
609            Ok(())
610        })
611    }
612
613    #[inline]
614    fn write_numeric_string<C: numericstring::Constraint>(
615        &mut self,
616        value: &str,
617    ) -> Result<(), Self::Error> {
618        self.write_bit_field_entry(false, true)?;
619        self.with_buffer(|w| {
620            Error::ensure_string_valid(Charset::Numeric, value)?;
621
622            w.write_extensible_bit_and_length_or_err(
623                C::EXTENSIBLE,
624                C::MIN,
625                C::MAX,
626                u64::MAX,
627                value.chars().count() as u64,
628            )?;
629
630            for char in value.chars().map(|c| c as u8) {
631                let char = match char - 32 {
632                    0 => 0,
633                    c => c - 15,
634                };
635                w.bits.write_bits_with_offset(&[char], 4)?;
636            }
637
638            Ok(())
639        })
640    }
641
642    #[inline]
643    fn write_printable_string<C: printablestring::Constraint>(
644        &mut self,
645        value: &str,
646    ) -> Result<(), Self::Error> {
647        self.write_bit_field_entry(false, true)?;
648        self.with_buffer(|w| {
649            Error::ensure_string_valid(Charset::Printable, value)?;
650
651            w.write_extensible_bit_and_length_or_err(
652                C::EXTENSIBLE,
653                C::MIN,
654                C::MAX,
655                u64::MAX,
656                value.chars().count() as u64,
657            )?;
658
659            for char in value.chars() {
660                w.bits.write_bits_with_offset(&[char as u8], 1)?;
661            }
662
663            Ok(())
664        })
665    }
666
667    #[inline]
668    fn write_visible_string<C: visiblestring::Constraint>(
669        &mut self,
670        value: &str,
671    ) -> Result<(), Self::Error> {
672        self.write_bit_field_entry(false, true)?;
673        self.with_buffer(|w| {
674            Error::ensure_string_valid(Charset::Visible, value)?;
675
676            w.write_extensible_bit_and_length_or_err(
677                C::EXTENSIBLE,
678                C::MIN,
679                C::MAX,
680                u64::MAX,
681                value.chars().count() as u64,
682            )?;
683
684            for char in value.chars() {
685                w.bits.write_bits_with_offset(&[char as u8], 1)?;
686            }
687
688            Ok(())
689        })
690    }
691
692    #[inline]
693    fn write_octet_string<C: octetstring::Constraint>(
694        &mut self,
695        value: &[u8],
696    ) -> Result<(), Self::Error> {
697        self.write_bit_field_entry(false, true)?;
698        self.with_buffer(|w| {
699            w.bits
700                .write_octetstring(C::MIN, C::MAX, C::EXTENSIBLE, value)
701        })
702    }
703
704    #[inline]
705    fn write_bit_string<C: bitstring::Constraint>(
706        &mut self,
707        value: &[u8],
708        bit_len: u64,
709    ) -> Result<(), Self::Error> {
710        self.write_bit_field_entry(false, true)?;
711        self.with_buffer(|w| {
712            w.bits
713                .write_bitstring(C::MIN, C::MAX, C::EXTENSIBLE, value, 0, bit_len)
714        })
715    }
716
717    #[inline]
718    fn write_boolean<C: boolean::Constraint>(&mut self, value: bool) -> Result<(), Self::Error> {
719        self.write_bit_field_entry(false, true)?;
720        self.with_buffer(|w| w.bits.write_bit(value))
721    }
722
723    #[inline]
724    fn write_null<C: null::Constraint>(&mut self, _value: &Null) -> Result<(), Self::Error> {
725        Ok(())
726    }
727}
728
729pub struct UperReader<B: ScopedBitRead> {
730    bits: B,
731    scope: Option<Scope>,
732    #[cfg(feature = "descriptive-deserialize-errors")]
733    scope_description: Vec<ScopeDescription>,
734}
735
736/*
737impl<B: ScopedBitRead> From<B> for UperReader<B> {
738    fn from(bits: B) -> Self {
739        UperReader { bits, scope: None }
740    }
741}*/
742
743impl<'a, I: Into<Bits<'a>>> From<I> for UperReader<Bits<'a>> {
744    fn from(bits: I) -> Self {
745        Self {
746            bits: bits.into(),
747            scope: None,
748            #[cfg(feature = "descriptive-deserialize-errors")]
749            scope_description: Vec::new(),
750        }
751    }
752}
753
754impl<B: ScopedBitRead> UperReader<B> {
755    #[inline]
756    fn read_length_determinant(
757        &mut self,
758        lower_bound: Option<u64>,
759        upper_bound: Option<u64>,
760    ) -> Result<u64, Error> {
761        #[allow(clippy::let_and_return)]
762        let result = self.bits.read_length_determinant(lower_bound, upper_bound);
763        #[cfg(feature = "descriptive-deserialize-errors")]
764        self.scope_description
765            .push(ScopeDescription::bits_length_determinant(
766                lower_bound,
767                upper_bound,
768                result.clone(),
769            ));
770        result
771    }
772
773    #[inline]
774    fn read_enumeration_index(
775        &mut self,
776        std_variants: u64,
777        extensible: bool,
778    ) -> Result<u64, Error> {
779        #[allow(clippy::let_and_return)]
780        let result = self.bits.read_enumeration_index(std_variants, extensible);
781        #[cfg(feature = "descriptive-deserialize-errors")]
782        self.scope_description
783            .push(ScopeDescription::bits_enumeration_index(
784                std_variants,
785                extensible,
786                result.clone(),
787            ));
788        result
789    }
790
791    #[inline]
792    fn read_choice_index(&mut self, std_variants: u64, extensible: bool) -> Result<u64, Error> {
793        #[allow(clippy::let_and_return)]
794        let result = self.bits.read_choice_index(std_variants, extensible);
795        #[cfg(feature = "descriptive-deserialize-errors")]
796        self.scope_description
797            .push(ScopeDescription::bits_choice_index(
798                std_variants,
799                extensible,
800                result.clone(),
801            ));
802        result
803    }
804
805    #[inline]
806    pub fn bits_remaining(&self) -> usize {
807        self.bits.remaining()
808    }
809
810    #[inline]
811    pub fn scope_pushed<T, F: FnOnce(&mut Self) -> Result<T, Error>>(
812        &mut self,
813        scope: Scope,
814        f: F,
815    ) -> Result<T, Error> {
816        let original = core::mem::replace(&mut self.scope, Some(scope));
817        let result = f(self);
818        if cfg!(debug_assertions) && result.is_ok() {
819            let scope = core::mem::replace(&mut self.scope, original);
820            // call to .unwrap() is save because this is supposed to be the original from above
821            debug_assert!(
822                scope.clone().unwrap().exhausted(),
823                "Not exhausted: {:?}",
824                scope.unwrap()
825            );
826        } else {
827            self.scope = original;
828        }
829        result
830    }
831
832    #[inline]
833    pub fn scope_stashed<T, F: FnOnce(&mut Self) -> Result<T, Error>>(
834        &mut self,
835        f: F,
836    ) -> Result<T, Error> {
837        let scope = self.scope.take();
838        let result = f(self);
839        self.scope = scope;
840        result
841    }
842
843    #[inline]
844    pub fn read_whole_sub_slice<T, F: FnOnce(&mut Self) -> Result<T, Error>>(
845        &mut self,
846        length_bytes: usize,
847        f: F,
848    ) -> Result<T, Error> {
849        let write_position = self.bits.pos() + (length_bytes * BYTE_LEN);
850        let write_original = core::mem::replace(&mut self.bits.len(), write_position);
851        let result = f(self);
852        // extend to original position
853        let len = self.bits.set_len(write_original);
854        #[cfg(feature = "descriptive-deserialize-errors")]
855        self.scope_description
856            .push(ScopeDescription::read_whole_sub_slice(
857                length_bytes,
858                write_position,
859                write_original,
860                len,
861                &result,
862            ));
863        debug_assert_eq!(write_original, len);
864        if result.is_ok() {
865            // on successful read, skip the slice
866            self.bits.set_pos(write_position);
867        }
868        result
869    }
870
871    #[inline]
872    pub fn read_bit_field_entry(&mut self, is_opt: bool) -> Result<Option<bool>, Error> {
873        #[allow(clippy::let_and_return)]
874        let result = if let Some(scope) = &mut self.scope {
875            scope.read_from_field(
876                #[cfg(feature = "descriptive-deserialize-errors")]
877                &mut self.scope_description,
878                &mut self.bits,
879                is_opt,
880            )
881        } else if is_opt {
882            Some(self.bits.read_bit()).transpose()
883        } else {
884            Ok(None)
885        };
886
887        #[cfg(feature = "descriptive-deserialize-errors")]
888        self.scope_description
889            .push(ScopeDescription::read_bit_field_entry(is_opt, &result));
890
891        result
892    }
893
894    #[inline]
895    pub fn with_buffer<T, F: FnOnce(&mut Self) -> Result<T, Error>>(
896        &mut self,
897        f: F,
898    ) -> Result<T, Error> {
899        if self
900            .scope
901            .as_ref()
902            .map(Scope::encode_as_open_type_field)
903            .unwrap_or(false)
904        {
905            let len = self.read_length_determinant(None, None)?;
906            self.read_whole_sub_slice(len as usize, f)
907        } else {
908            f(self)
909        }
910    }
911}
912
913impl<B: ScopedBitRead> Reader for UperReader<B> {
914    type Error = Error;
915
916    #[inline]
917    fn read<T: Readable>(&mut self) -> Result<T, Self::Error>
918    where
919        Self: Sized,
920    {
921        #[allow(clippy::let_and_return)]
922        let value = T::read(self);
923        #[cfg(feature = "descriptive-deserialize-errors")]
924        let value = value.map_err(|mut e| {
925            e.0.description = core::mem::take(&mut self.scope_description);
926            e
927        });
928        value
929    }
930
931    #[inline]
932    fn read_sequence<
933        C: sequence::Constraint,
934        S: Sized,
935        F: Fn(&mut Self) -> Result<S, Self::Error>,
936    >(
937        &mut self,
938        f: F,
939    ) -> Result<S, Self::Error> {
940        #[cfg(feature = "descriptive-deserialize-errors")]
941        self.scope_description
942            .push(ScopeDescription::sequence::<C>());
943
944        let _ = self.read_bit_field_entry(false);
945        #[allow(clippy::let_and_return)]
946        let result = self.with_buffer(|r| {
947            let extension_after = if let Some(extension_after) = C::EXTENDED_AFTER_FIELD {
948                let bit_pos = r.bits.pos();
949                if r.bits.read_bit()? {
950                    Some((extension_after, bit_pos))
951                } else {
952                    None
953                }
954            } else {
955                None
956            };
957
958            // In UPER the values for all OPTIONAL flags are written before any field
959            // value is written. This remembers their position, so a later call of `read_opt`
960            // can retrieve them from the buffer
961            if r.bits.remaining() < C::STD_OPTIONAL_FIELDS as usize {
962                return Err(ErrorKind::EndOfStream.into());
963            }
964
965            let range = r.bits.pos()..r.bits.pos() + C::STD_OPTIONAL_FIELDS as usize;
966            r.bits.set_pos(range.end); // skip optional
967
968            if let Some((extension_after, bit_pos)) = extension_after {
969                r.scope_pushed(
970                    Scope::ExtensibleSequence {
971                        name: C::NAME,
972                        bit_pos,
973                        opt_bit_field: Some(range),
974                        calls_until_ext_bitfield: (extension_after + 1) as usize,
975                        number_of_ext_fields: (C::FIELD_COUNT - (extension_after + 1)) as usize,
976                    },
977                    f,
978                )
979            } else {
980                r.scope_pushed(Scope::OptBitField(range), f)
981            }
982        });
983
984        #[cfg(feature = "descriptive-deserialize-errors")]
985        self.scope_description.push(ScopeDescription::End(C::NAME));
986
987        result
988    }
989
990    #[inline]
991    fn read_sequence_of<C: sequenceof::Constraint, T: ReadableType>(
992        &mut self,
993    ) -> Result<Vec<T::Type>, Self::Error> {
994        #[cfg(feature = "descriptive-deserialize-errors")]
995        self.scope_description
996            .push(ScopeDescription::sequence_of::<C>());
997
998        let _ = self.read_bit_field_entry(false)?;
999        #[allow(clippy::let_and_return)]
1000        self.with_buffer(|r| {
1001            let len = if C::EXTENSIBLE {
1002                let extensible = r.bits.read_bit()?;
1003                if extensible {
1004                    r.read_length_determinant(None, None)?
1005                } else {
1006                    r.read_length_determinant(C::MIN, C::MAX)?
1007                }
1008            } else {
1009                r.read_length_determinant(C::MIN, C::MAX)?
1010            };
1011
1012            if len > 0 {
1013                r.scope_stashed(|r| {
1014                    let mut vec = Vec::with_capacity(len as usize);
1015                    for _ in 0..len {
1016                        vec.push(T::read_value(r)?);
1017                    }
1018                    Ok(vec)
1019                })
1020            } else {
1021                Ok(Vec::new())
1022            }
1023        })
1024    }
1025
1026    #[inline]
1027    fn read_set<C: set::Constraint, S: Sized, F: Fn(&mut Self) -> Result<S, Self::Error>>(
1028        &mut self,
1029        f: F,
1030    ) -> Result<S, Self::Error> {
1031        self.read_sequence::<C, S, F>(f)
1032    }
1033
1034    #[inline]
1035    fn read_set_of<C: setof::Constraint, T: ReadableType>(
1036        &mut self,
1037    ) -> Result<Vec<<T as ReadableType>::Type>, Self::Error> {
1038        self.read_sequence_of::<C, T>()
1039    }
1040
1041    #[inline]
1042    fn read_enumerated<C: enumerated::Constraint>(&mut self) -> Result<C, Self::Error> {
1043        #[cfg(feature = "descriptive-deserialize-errors")]
1044        self.scope_description
1045            .push(ScopeDescription::enumerated::<C>());
1046
1047        let _ = self.read_bit_field_entry(false)?;
1048        #[allow(clippy::let_and_return)]
1049        let result = self.with_buffer(|r| r.read_enumeration_index(C::STD_VARIANT_COUNT, C::EXTENSIBLE))
1050            .and_then(|index| {
1051                #[cfg(feature = "descriptive-deserialize-errors")]
1052                if index >= C::VARIANT_COUNT {
1053                    self.scope_description
1054                        .push(ScopeDescription::warning(format!(
1055                            "Index of extensible enum {} outside of known variants, clamping index value from {index} to {}",
1056                            C::NAME,
1057                            C::VARIANT_COUNT.saturating_sub(1)
1058                        )));
1059                }
1060                let result = C::from_choice_index(index)
1061                    .ok_or_else(|| ErrorKind::InvalidChoiceIndex(index, C::VARIANT_COUNT).into());
1062                #[cfg(feature = "descriptive-deserialize-errors")]
1063                self.scope_description.push(ScopeDescription::Result(
1064                    result.as_ref().map(|_| index.to_string()).map_err(Error::clone)
1065                ));
1066                result
1067            });
1068
1069        #[cfg(feature = "descriptive-deserialize-errors")]
1070        self.scope_description.push(ScopeDescription::End(C::NAME));
1071
1072        result
1073    }
1074
1075    #[inline]
1076    fn read_choice<C: choice::Constraint>(&mut self) -> Result<C, Self::Error> {
1077        #[cfg(feature = "descriptive-deserialize-errors")]
1078        self.scope_description.push(ScopeDescription::choice::<C>());
1079
1080        let _ = self.read_bit_field_entry(false)?;
1081        #[allow(clippy::let_and_return)]
1082        let result = self.scope_stashed(|r| {
1083            let index = r.read_choice_index(C::STD_VARIANT_COUNT, C::EXTENSIBLE)?;
1084            let result = if index >= C::STD_VARIANT_COUNT {
1085                let length = r.read_length_determinant(None, None)?;
1086                r.read_whole_sub_slice(length as usize, |r| Ok((index, C::read_content(index, r)?)))
1087            } else {
1088                Ok((index, C::read_content(index, r)?))
1089            }
1090            .and_then(|(index, content)| {
1091                content.ok_or_else(|| ErrorKind::InvalidChoiceIndex(index, C::VARIANT_COUNT).into())
1092            });
1093            #[cfg(feature = "descriptive-deserialize-errors")]
1094            r.scope_description.push(ScopeDescription::Result(
1095                result
1096                    .as_ref()
1097                    .map(|_| index.to_string())
1098                    .map_err(Error::clone),
1099            ));
1100            result
1101        });
1102
1103        #[cfg(feature = "descriptive-deserialize-errors")]
1104        self.scope_description.push(ScopeDescription::End(C::NAME));
1105
1106        result
1107    }
1108
1109    #[inline]
1110    fn read_opt<T: ReadableType>(
1111        &mut self,
1112    ) -> Result<Option<<T as ReadableType>::Type>, Self::Error> {
1113        #[cfg(feature = "descriptive-deserialize-errors")]
1114        self.scope_description.push(ScopeDescription::optional());
1115
1116        // unwrap: as opt-field this must and will return some value
1117        if self.read_bit_field_entry(true)?.unwrap() {
1118            self.with_buffer(|w| w.scope_stashed(T::read_value))
1119                .map(Some)
1120        } else {
1121            Ok(None)
1122        }
1123    }
1124
1125    #[inline]
1126    fn read_default<C: default::Constraint<Owned = T::Type>, T: ReadableType>(
1127        &mut self,
1128    ) -> Result<T::Type, Self::Error> {
1129        #[cfg(feature = "descriptive-deserialize-errors")]
1130        self.scope_description
1131            .push(ScopeDescription::default_type());
1132
1133        // unwrap: as opt-field this must and will return some value
1134        if self.read_bit_field_entry(true)?.unwrap() {
1135            self.scope_stashed(T::read_value)
1136        } else {
1137            Ok(C::DEFAULT_VALUE.to_owned())
1138        }
1139    }
1140
1141    #[inline]
1142    #[allow(clippy::redundant_pattern_matching)] // allow for const_*!
1143    fn read_number<T: numbers::Number, C: numbers::Constraint<T>>(
1144        &mut self,
1145    ) -> Result<T, Self::Error> {
1146        #[cfg(feature = "descriptive-deserialize-errors")]
1147        self.scope_description
1148            .push(ScopeDescription::number::<T, C>());
1149
1150        let _ = self.read_bit_field_entry(false)?;
1151        self.with_buffer(|r| {
1152            let unconstrained = if C::EXTENSIBLE {
1153                r.bits.read_bit()?
1154            } else {
1155                const_is_none!(C::MIN) && const_is_none!(C::MAX)
1156            };
1157
1158            let result = if unconstrained {
1159                r.bits.read_unconstrained_whole_number()
1160            } else {
1161                r.bits.read_constrained_whole_number(
1162                    const_unwrap_or!(C::MIN, 0),
1163                    const_unwrap_or!(C::MAX, i64::MAX),
1164                )
1165            };
1166
1167            #[cfg(feature = "descriptive-deserialize-errors")]
1168            r.scope_description.push(ScopeDescription::Result(
1169                result
1170                    .as_ref()
1171                    .map(ToString::to_string)
1172                    .map_err(|e| e.clone()),
1173            ));
1174
1175            result.map(T::from_i64)
1176        })
1177    }
1178
1179    #[inline]
1180    fn read_utf8string<C: utf8string::Constraint>(&mut self) -> Result<String, Self::Error> {
1181        #[cfg(feature = "descriptive-deserialize-errors")]
1182        self.scope_description
1183            .push(ScopeDescription::utf8string::<C>());
1184
1185        let _ = self.read_bit_field_entry(false)?;
1186        #[allow(clippy::let_and_return)]
1187        let result = self.with_buffer(|r| {
1188            // ITU-T X.691 | ISO/IEC 8825-2:2015, chapter 30.3
1189            // For 'known-multiplier character string types' there is no min/max in the encoding
1190            let octets = r.bits.read_octetstring(None, None, false)?;
1191            String::from_utf8(octets).map_err(|e| ErrorKind::FromUtf8Error(e).into())
1192        });
1193
1194        #[cfg(feature = "descriptive-deserialize-errors")]
1195        self.scope_description
1196            .push(ScopeDescription::Result(result.clone()));
1197
1198        result
1199    }
1200
1201    #[inline]
1202    fn read_ia5string<C: ia5string::Constraint>(&mut self) -> Result<String, Self::Error> {
1203        #[cfg(feature = "descriptive-deserialize-errors")]
1204        self.scope_description
1205            .push(ScopeDescription::ia5string::<C>());
1206
1207        let _ = self.read_bit_field_entry(false)?;
1208        #[allow(clippy::let_and_return)]
1209        let result = self.with_buffer(|r| {
1210            let len = if C::EXTENSIBLE && r.bits.read_bit()? {
1211                r.read_length_determinant(None, None)?
1212            } else {
1213                r.read_length_determinant(C::MIN, C::MAX)?
1214            };
1215
1216            let mut buffer = vec![0u8; len as usize];
1217            for i in 0..len as usize {
1218                r.bits.read_bits_with_offset(&mut buffer[i..i + 1], 1)?;
1219            }
1220
1221            String::from_utf8(buffer).map_err(|e| ErrorKind::FromUtf8Error(e).into())
1222        });
1223
1224        #[cfg(feature = "descriptive-deserialize-errors")]
1225        self.scope_description
1226            .push(ScopeDescription::Result(result.clone()));
1227
1228        result
1229    }
1230
1231    #[inline]
1232    fn read_numeric_string<C: numericstring::Constraint>(&mut self) -> Result<String, Self::Error> {
1233        #[cfg(feature = "descriptive-deserialize-errors")]
1234        self.scope_description
1235            .push(ScopeDescription::numeric_string::<C>());
1236
1237        let _ = self.read_bit_field_entry(false)?;
1238        #[allow(clippy::let_and_return)]
1239        let result = self.with_buffer(|r| {
1240            let len = if C::EXTENSIBLE && r.bits.read_bit()? {
1241                r.read_length_determinant(None, None)?
1242            } else {
1243                r.read_length_determinant(C::MIN, C::MAX)?
1244            };
1245
1246            let mut buffer = vec![0u8; len as usize];
1247            for i in 0..len as usize {
1248                r.bits.read_bits_with_offset(&mut buffer[i..i + 1], 4)?;
1249                match buffer[i] {
1250                    0_u8 => buffer[i] = 32_u8,
1251                    c => buffer[i] = 32_u8 + 15 + c,
1252                }
1253            }
1254
1255            String::from_utf8(buffer).map_err(|e| ErrorKind::FromUtf8Error(e).into())
1256        });
1257
1258        #[cfg(feature = "descriptive-deserialize-errors")]
1259        self.scope_description
1260            .push(ScopeDescription::Result(result.clone()));
1261
1262        result
1263    }
1264
1265    #[inline]
1266    fn read_printable_string<C: printablestring::Constraint>(
1267        &mut self,
1268    ) -> Result<String, Self::Error> {
1269        #[cfg(feature = "descriptive-deserialize-errors")]
1270        self.scope_description
1271            .push(ScopeDescription::printable_string::<C>());
1272
1273        let _ = self.read_bit_field_entry(false)?;
1274        #[allow(clippy::let_and_return)]
1275        let result = self.with_buffer(|r| {
1276            let len = if C::EXTENSIBLE && r.bits.read_bit()? {
1277                r.read_length_determinant(None, None)?
1278            } else {
1279                r.read_length_determinant(C::MIN, C::MAX)?
1280            };
1281
1282            let mut buffer = vec![0u8; len as usize];
1283            buffer
1284                .chunks_exact_mut(1)
1285                .try_for_each(|chunk| r.bits.read_bits_with_offset(chunk, 1))?;
1286
1287            String::from_utf8(buffer).map_err(|e| ErrorKind::FromUtf8Error(e).into())
1288        });
1289
1290        #[cfg(feature = "descriptive-deserialize-errors")]
1291        self.scope_description
1292            .push(ScopeDescription::Result(result.clone()));
1293
1294        result
1295    }
1296
1297    #[inline]
1298    fn read_visible_string<C: visiblestring::Constraint>(&mut self) -> Result<String, Self::Error> {
1299        #[cfg(feature = "descriptive-deserialize-errors")]
1300        self.scope_description
1301            .push(ScopeDescription::visible_string::<C>());
1302
1303        let _ = self.read_bit_field_entry(false)?;
1304        #[allow(clippy::let_and_return)]
1305        let result = self.with_buffer(|r| {
1306            let len = if C::EXTENSIBLE && r.bits.read_bit()? {
1307                r.read_length_determinant(None, None)?
1308            } else {
1309                r.read_length_determinant(C::MIN, C::MAX)?
1310            };
1311
1312            let mut buffer = vec![0u8; len as usize];
1313            buffer
1314                .chunks_exact_mut(1)
1315                .try_for_each(|chunk| r.bits.read_bits_with_offset(chunk, 1))?;
1316
1317            String::from_utf8(buffer).map_err(|e| ErrorKind::FromUtf8Error(e).into())
1318        });
1319
1320        #[cfg(feature = "descriptive-deserialize-errors")]
1321        self.scope_description
1322            .push(ScopeDescription::Result(result.clone()));
1323
1324        result
1325    }
1326
1327    #[inline]
1328    fn read_octet_string<C: octetstring::Constraint>(&mut self) -> Result<Vec<u8>, Self::Error> {
1329        #[cfg(feature = "descriptive-deserialize-errors")]
1330        self.scope_description
1331            .push(ScopeDescription::octet_string::<C>());
1332
1333        let _ = self.read_bit_field_entry(false)?;
1334        #[allow(clippy::let_and_return)]
1335        let result = self.with_buffer(|r| r.bits.read_octetstring(C::MIN, C::MAX, C::EXTENSIBLE));
1336
1337        #[cfg(feature = "descriptive-deserialize-errors")]
1338        self.scope_description.push(ScopeDescription::Result(
1339            result
1340                .as_ref()
1341                .map(|s| {
1342                    s.iter()
1343                        .map(|v| format!("{v:02x}"))
1344                        .collect::<Vec<_>>()
1345                        .join(" ")
1346                })
1347                .map_err(|e| e.clone()),
1348        ));
1349
1350        result
1351    }
1352
1353    #[inline]
1354    fn read_bit_string<C: bitstring::Constraint>(&mut self) -> Result<(Vec<u8>, u64), Self::Error> {
1355        #[cfg(feature = "descriptive-deserialize-errors")]
1356        self.scope_description
1357            .push(ScopeDescription::bit_string::<C>());
1358
1359        let _ = self.read_bit_field_entry(false)?;
1360        #[allow(clippy::let_and_return)]
1361        let result = self.with_buffer(|r| r.bits.read_bitstring(C::MIN, C::MAX, C::EXTENSIBLE));
1362
1363        #[cfg(feature = "descriptive-deserialize-errors")]
1364        self.scope_description.push(ScopeDescription::Result(
1365            result
1366                .as_ref()
1367                .map(|(bits, len)| {
1368                    format!(
1369                        "len={len} bits=[{}]",
1370                        bits.iter()
1371                            .map(|v| format!("{v:02x}"))
1372                            .collect::<Vec<_>>()
1373                            .join(" ")
1374                    )
1375                })
1376                .map_err(|e| e.clone()),
1377        ));
1378
1379        result
1380    }
1381
1382    #[inline]
1383    fn read_boolean<C: boolean::Constraint>(&mut self) -> Result<bool, Self::Error> {
1384        #[cfg(feature = "descriptive-deserialize-errors")]
1385        self.scope_description
1386            .push(ScopeDescription::boolean::<C>());
1387
1388        let _ = self.read_bit_field_entry(false)?;
1389        #[allow(clippy::let_and_return)]
1390        let result = self.with_buffer(|r| r.bits.read_boolean());
1391
1392        #[cfg(feature = "descriptive-deserialize-errors")]
1393        self.scope_description.push(ScopeDescription::Result(
1394            result
1395                .as_ref()
1396                .map(|v| v.to_string())
1397                .map_err(|e| e.clone()),
1398        ));
1399
1400        result
1401    }
1402
1403    #[inline]
1404    fn read_null<C: null::Constraint>(&mut self) -> Result<Null, Self::Error> {
1405        Ok(Null)
1406    }
1407}
1408
1409pub trait UperDecodable<'a, I: Into<Bits<'a>> + 'a> {
1410    fn decode_from_uper(bits: I) -> Result<Self, Error>
1411    where
1412        Self: Sized;
1413}
1414
1415impl<'a, R: Readable, I: Into<Bits<'a>> + 'a> UperDecodable<'a, I> for R {
1416    fn decode_from_uper(bits: I) -> Result<Self, Error>
1417    where
1418        Self: Sized,
1419    {
1420        let mut reader = UperReader::from(bits);
1421        Self::read(&mut reader)
1422    }
1423}
1424
1425#[cfg(feature = "descriptive-deserialize-errors")]
1426#[cfg_attr(
1427    feature = "descriptive-deserialize-errors",
1428    derive(Debug, Clone, PartialEq)
1429)]
1430pub enum ScopeDescription {
1431    Root(Vec<ScopeDescription>),
1432    Sequence {
1433        tag: asn1rs_model::model::Tag,
1434        name: &'static str,
1435        std_optional_fields: u64,
1436        field_count: u64,
1437        extended_after_field: Option<u64>,
1438    },
1439    SequenceOf {
1440        tag: asn1rs_model::model::Tag,
1441        min: Option<u64>,
1442        max: Option<u64>,
1443        extensible: bool,
1444    },
1445    Enumerated {
1446        tag: asn1rs_model::model::Tag,
1447        name: &'static str,
1448        variant_count: u64,
1449        std_variant_count: u64,
1450        extensible: bool,
1451    },
1452    Choice {
1453        tag: asn1rs_model::model::Tag,
1454        name: &'static str,
1455        variant_count: u64,
1456        std_variant_count: u64,
1457        extensible: bool,
1458    },
1459    Optional,
1460    Default,
1461    Number {
1462        tag: asn1rs_model::model::Tag,
1463        min: Option<i64>,
1464        max: Option<i64>,
1465        extensible: bool,
1466    },
1467    Utf8String {
1468        tag: asn1rs_model::model::Tag,
1469        min: Option<u64>,
1470        max: Option<u64>,
1471        extensible: bool,
1472    },
1473    Ia5String {
1474        tag: asn1rs_model::model::Tag,
1475        min: Option<u64>,
1476        max: Option<u64>,
1477        extensible: bool,
1478    },
1479    NumericString {
1480        tag: asn1rs_model::model::Tag,
1481        min: Option<u64>,
1482        max: Option<u64>,
1483        extensible: bool,
1484    },
1485    PrintableString {
1486        tag: asn1rs_model::model::Tag,
1487        min: Option<u64>,
1488        max: Option<u64>,
1489        extensible: bool,
1490    },
1491    VisibleString {
1492        tag: asn1rs_model::model::Tag,
1493        min: Option<u64>,
1494        max: Option<u64>,
1495        extensible: bool,
1496    },
1497    OctetString {
1498        tag: asn1rs_model::model::Tag,
1499        min: Option<u64>,
1500        max: Option<u64>,
1501        extensible: bool,
1502    },
1503    BitString {
1504        tag: asn1rs_model::model::Tag,
1505        min: Option<u64>,
1506        max: Option<u64>,
1507        extensible: bool,
1508    },
1509    Boolean {
1510        tag: asn1rs_model::model::Tag,
1511    },
1512    Result(Result<String, Error>),
1513    BitsLengthDeterminant {
1514        lower_bound: Option<u64>,
1515        upper_bound: Option<u64>,
1516        result: Result<u64, Error>,
1517    },
1518    BitsEnumerationIndex {
1519        std_variants: u64,
1520        extensible: bool,
1521        result: Result<u64, Error>,
1522    },
1523    BitsChoiceIndex {
1524        std_variants: u64,
1525        extensible: bool,
1526        result: Result<u64, Error>,
1527    },
1528    ReadWholeSubSlice {
1529        length_bytes: usize,
1530        write_position: usize,
1531        write_original: usize,
1532        len: usize,
1533        result: Result<(), Error>,
1534    },
1535    ReadBitFieldEntry {
1536        is_opt: bool,
1537        result: Result<Option<bool>, Error>,
1538    },
1539    Warning {
1540        message: String,
1541    },
1542    Error {
1543        message: String,
1544    },
1545    End(&'static str),
1546}
1547
1548#[cfg(feature = "descriptive-deserialize-errors")]
1549mod scope_description_impl {
1550    use super::*;
1551
1552    impl ScopeDescription {
1553        #[inline]
1554        pub fn sequence<C: sequence::Constraint>() -> Self {
1555            Self::Sequence {
1556                tag: C::TAG,
1557                name: C::NAME,
1558                std_optional_fields: C::STD_OPTIONAL_FIELDS,
1559                field_count: C::FIELD_COUNT,
1560                extended_after_field: C::EXTENDED_AFTER_FIELD,
1561            }
1562        }
1563
1564        #[inline]
1565        pub fn sequence_of<C: sequenceof::Constraint>() -> Self {
1566            Self::SequenceOf {
1567                tag: C::TAG,
1568                min: C::MIN,
1569                max: C::MAX,
1570                extensible: C::EXTENSIBLE,
1571            }
1572        }
1573
1574        #[inline]
1575        pub fn enumerated<C: enumerated::Constraint>() -> Self {
1576            Self::Enumerated {
1577                tag: C::TAG,
1578                name: C::NAME,
1579                variant_count: C::VARIANT_COUNT,
1580                std_variant_count: C::STD_VARIANT_COUNT,
1581                extensible: C::EXTENSIBLE,
1582            }
1583        }
1584
1585        #[inline]
1586        pub fn choice<C: choice::Constraint>() -> Self {
1587            Self::Choice {
1588                tag: C::TAG,
1589                name: C::NAME,
1590                variant_count: C::VARIANT_COUNT,
1591                std_variant_count: C::STD_VARIANT_COUNT,
1592                extensible: C::EXTENSIBLE,
1593            }
1594        }
1595
1596        #[inline]
1597        pub fn optional() -> Self {
1598            ScopeDescription::Optional
1599        }
1600
1601        #[inline]
1602        pub fn default_type() -> Self {
1603            ScopeDescription::Default
1604        }
1605
1606        #[inline]
1607        pub fn number<T: numbers::Number, C: numbers::Constraint<T>>() -> Self {
1608            Self::Number {
1609                tag: C::TAG,
1610                min: C::MIN,
1611                max: C::MAX,
1612                extensible: C::EXTENSIBLE,
1613            }
1614        }
1615
1616        #[inline]
1617        pub fn utf8string<C: utf8string::Constraint>() -> Self {
1618            Self::Utf8String {
1619                tag: C::TAG,
1620                min: C::MIN,
1621                max: C::MAX,
1622                extensible: C::EXTENSIBLE,
1623            }
1624        }
1625
1626        #[inline]
1627        pub fn ia5string<C: ia5string::Constraint>() -> Self {
1628            Self::Ia5String {
1629                tag: C::TAG,
1630                min: C::MIN,
1631                max: C::MAX,
1632                extensible: C::EXTENSIBLE,
1633            }
1634        }
1635
1636        #[inline]
1637        pub fn numeric_string<C: numericstring::Constraint>() -> Self {
1638            Self::NumericString {
1639                tag: C::TAG,
1640                min: C::MIN,
1641                max: C::MAX,
1642                extensible: C::EXTENSIBLE,
1643            }
1644        }
1645
1646        #[inline]
1647        pub fn printable_string<C: printablestring::Constraint>() -> Self {
1648            Self::PrintableString {
1649                tag: C::TAG,
1650                min: C::MIN,
1651                max: C::MAX,
1652                extensible: C::EXTENSIBLE,
1653            }
1654        }
1655
1656        #[inline]
1657        pub fn visible_string<C: visiblestring::Constraint>() -> Self {
1658            Self::VisibleString {
1659                tag: C::TAG,
1660                min: C::MIN,
1661                max: C::MAX,
1662                extensible: C::EXTENSIBLE,
1663            }
1664        }
1665
1666        #[inline]
1667        pub fn octet_string<C: octetstring::Constraint>() -> Self {
1668            Self::OctetString {
1669                tag: C::TAG,
1670                min: C::MIN,
1671                max: C::MAX,
1672                extensible: C::EXTENSIBLE,
1673            }
1674        }
1675
1676        #[inline]
1677        pub fn bit_string<C: bitstring::Constraint>() -> Self {
1678            Self::BitString {
1679                tag: C::TAG,
1680                min: C::MIN,
1681                max: C::MAX,
1682                extensible: C::EXTENSIBLE,
1683            }
1684        }
1685
1686        #[inline]
1687        pub fn boolean<C: boolean::Constraint>() -> Self {
1688            Self::Boolean { tag: C::TAG }
1689        }
1690
1691        #[inline]
1692        pub fn bits_length_determinant(
1693            lower_bound: Option<u64>,
1694            upper_bound: Option<u64>,
1695            result: Result<u64, Error>,
1696        ) -> Self {
1697            Self::BitsLengthDeterminant {
1698                lower_bound,
1699                upper_bound,
1700                result,
1701            }
1702        }
1703
1704        #[inline]
1705        pub fn bits_enumeration_index(
1706            std_variants: u64,
1707            extensible: bool,
1708            result: Result<u64, Error>,
1709        ) -> Self {
1710            Self::BitsEnumerationIndex {
1711                std_variants,
1712                extensible,
1713                result,
1714            }
1715        }
1716
1717        #[inline]
1718        pub fn bits_choice_index(
1719            std_variants: u64,
1720            extensible: bool,
1721            result: Result<u64, Error>,
1722        ) -> Self {
1723            Self::BitsChoiceIndex {
1724                std_variants,
1725                extensible,
1726                result,
1727            }
1728        }
1729
1730        #[inline]
1731        pub fn read_whole_sub_slice<T>(
1732            length_bytes: usize,
1733            write_position: usize,
1734            write_original: usize,
1735            len: usize,
1736            result: &Result<T, Error>,
1737        ) -> Self {
1738            Self::ReadWholeSubSlice {
1739                length_bytes,
1740                write_position,
1741                write_original,
1742                len,
1743                result: result.as_ref().map(drop).map_err(|e| e.clone()),
1744            }
1745        }
1746
1747        #[inline]
1748        pub fn read_bit_field_entry(is_opt: bool, result: &Result<Option<bool>, Error>) -> Self {
1749            Self::ReadBitFieldEntry {
1750                is_opt,
1751                result: result.clone(),
1752            }
1753        }
1754
1755        #[inline]
1756        pub fn warning(s: impl Into<String>) -> Self {
1757            Self::Warning { message: s.into() }
1758        }
1759    }
1760}