11use core:: cmp:: Ordering ;
2+ use core:: num;
23
34use super :: { AnyRef , Choice } ;
45use crate :: encode:: Encode ;
56use crate :: {
67 Class , Decode , DecodeValue , DerOrd , EncodeValue , Error , FixedTag , Header , Length , Reader ,
7- SliceReader , Tag , TagNumber , Tagged , ValueOrd , Writer ,
8+ SliceReader , Tag , TagMode , TagNumber , Tagged , ValueOrd , Writer ,
89} ;
910
1011/// Application, Context-specific or Private class field which wraps an owned inner value.
@@ -43,9 +44,13 @@ impl<T, const TAG: u16, const CLASS: u8> CustomClass<T, TAG, CLASS> {
4344 where
4445 T : Decode < ' a > ,
4546 {
46- decode_with ( reader, Class :: from ( CLASS ) , TagNumber ( TAG ) , |reader| {
47- Self :: decode ( reader)
48- } )
47+ match AnyCustomClassExplicit :: decode_explicit ( Class :: from ( CLASS ) , TagNumber ( TAG ) , reader) {
48+ Ok ( Some ( custom) ) => Ok ( Some ( Self {
49+ value : custom. value ,
50+ } ) ) ,
51+ Ok ( None ) => Ok ( None ) ,
52+ Err ( err) => Err ( err) ,
53+ }
4954 }
5055}
5156
@@ -72,14 +77,14 @@ fn decode_with<'a, F, R: Reader<'a>, E, T>(
7277 f : F ,
7378) -> Result < Option < T > , E >
7479where
75- F : FnOnce ( & mut R ) -> Result < T , E > ,
80+ F : FnOnce ( Tag , & mut R ) -> Result < T , E > ,
7681 E : From < Error > ,
7782{
7883 while let Some ( tag) = Tag :: peek_optional ( reader) ? {
7984 if is_unskippable_tag ( tag, expected_class, expected_number) {
8085 break ;
8186 } else if tag. number ( ) == expected_number {
82- return Some ( f ( reader) ) . transpose ( ) ;
87+ return Some ( f ( tag , reader) ) . transpose ( ) ;
8388 } else {
8489 AnyRef :: decode ( reader) ?;
8590 }
@@ -99,29 +104,71 @@ impl<T, const TAG: u16, const CLASS: u8> CustomClassImplicit<T, TAG, CLASS> {
99104 where
100105 T : DecodeValue < ' a > + Tagged ,
101106 {
102- match decode_implicit ( Class :: from ( CLASS ) , TagNumber ( TAG ) , reader) {
103- Ok ( Some ( value) ) => Ok ( Some ( Self { value } ) ) ,
107+ match AnyCustomClassImplicit :: decode_implicit ( Class :: from ( CLASS ) , TagNumber ( TAG ) , reader) {
108+ Ok ( Some ( custom) ) => Ok ( Some ( Self {
109+ value : custom. value ,
110+ } ) ) ,
104111 Ok ( None ) => Ok ( None ) ,
105112 Err ( err) => Err ( err) ,
106113 }
107114 }
108115}
109116
110- pub fn decode_implicit < ' a , R : Reader < ' a > , T : Tagged + DecodeValue < ' a > > (
111- class : Class ,
112- number : TagNumber ,
113- reader : & mut R ,
114- ) -> Result < Option < T > , T :: Error > {
115- decode_with :: < _ , _ , T :: Error , _ > ( reader, class, number, |reader| {
116- let header = Header :: decode ( reader) ?;
117- let value = T :: decode_value ( reader, header) ?;
117+ pub struct AnyCustomClassExplicit < T > {
118+ pub tag_number : TagNumber ,
119+ pub constructed : bool ,
120+ pub value : T ,
121+ }
118122
119- if header. tag . is_constructed ( ) != value. tag ( ) . is_constructed ( ) {
120- return Err ( header. tag . non_canonical_error ( ) . into ( ) ) ;
121- }
123+ pub struct AnyCustomClassImplicit < T > {
124+ pub tag_number : TagNumber ,
125+ pub constructed : bool ,
126+ pub value : T ,
127+ }
122128
123- Ok ( value)
124- } )
129+ impl < ' a , T > AnyCustomClassExplicit < T >
130+ where
131+ T : Decode < ' a > ,
132+ {
133+ pub fn decode_explicit < R : Reader < ' a > > (
134+ class : Class ,
135+ number : TagNumber ,
136+ reader : & mut R ,
137+ ) -> Result < Option < Self > , T :: Error > {
138+ decode_with ( reader, class, number, |tag, reader| {
139+ Ok ( Self {
140+ value : T :: decode ( reader) ?,
141+ tag_number : tag. number ( ) ,
142+ constructed : tag. is_constructed ( ) ,
143+ } )
144+ } )
145+ }
146+ }
147+
148+ impl < ' a , T > AnyCustomClassImplicit < T >
149+ where
150+ T : Tagged + DecodeValue < ' a > ,
151+ {
152+ pub fn decode_implicit < R : Reader < ' a > > (
153+ class : Class ,
154+ number : TagNumber ,
155+ reader : & mut R ,
156+ ) -> Result < Option < Self > , T :: Error > {
157+ decode_with :: < _ , _ , T :: Error , _ > ( reader, class, number, |_tag, reader| {
158+ let header = Header :: decode ( reader) ?;
159+ let value = T :: decode_value ( reader, header) ?;
160+
161+ if header. tag . is_constructed ( ) != value. tag ( ) . is_constructed ( ) {
162+ return Err ( header. tag . non_canonical_error ( ) . into ( ) ) ;
163+ }
164+
165+ Ok ( Self {
166+ tag_number : header. tag . number ( ) ,
167+ constructed : header. tag . is_constructed ( ) ,
168+ value,
169+ } )
170+ } )
171+ }
125172}
126173
127174impl < ' a , T , const TAG : u16 , const CLASS : u8 > Choice < ' a > for CustomClass < T , TAG , CLASS >
0 commit comments