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 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 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 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 let range = pos + 1..buffer.write_position;
126 *self = Scope::AllBitField(range);
127 } else {
128 *self = Scope::ExtensibleSequenceEmpty(name);
129 }
130 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 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 }
215 let range = bits.pos()..bits.pos() + *number_of_ext_fields;
216 bits.set_pos(range.start + read_number_of_ext_fields); *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 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)] 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 w.bits.write_bit(false)?;
383 Some((extension_after, bit_pos))
384 } else {
385 None
386 };
387
388 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 if let Err(e) = w.bits.write_bit(false) {
397 w.bits.write_position = write_pos; 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)] 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 w.bits
483 .write_choice_index(C::STD_VARIANT_COUNT, C::EXTENSIBLE, index)?;
484
485 if index >= C::STD_VARIANT_COUNT {
486 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)] 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)] 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)] 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 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 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
736impl<'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 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 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 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 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); 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 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 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)] 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 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}