8
8
import pprint
9
9
import traceback
10
10
from collections .abc import Collection
11
- from enum import Enum
11
+ from enum import Enum , EnumType
12
12
from typing import TYPE_CHECKING , Any , BinaryIO , Callable , ClassVar , Optional , TypeVar , Union , get_type_hints
13
13
14
14
from chia_rs .sized_bytes import bytes32
@@ -130,6 +130,10 @@ def is_type_Dict(f_type: object) -> bool:
130
130
return get_origin (f_type ) is dict or f_type is dict
131
131
132
132
133
+ def is_type_Enum (f_type : object ) -> bool :
134
+ return type (f_type ) is EnumType
135
+
136
+
133
137
def convert_optional (convert_func : ConvertFunctionType , item : Any ) -> Any :
134
138
if item is None :
135
139
return None
@@ -156,6 +160,10 @@ def convert_dict(
156
160
return {key_converter (key ): value_converter (value ) for key , value in mapping .items ()}
157
161
158
162
163
+ def convert_enum (convert_func : ConvertFunctionType , enum : Enum ) -> Any :
164
+ return convert_func (enum .value )
165
+
166
+
159
167
def convert_hex_string (item : str ) -> bytes :
160
168
if not isinstance (item , str ):
161
169
raise InvalidTypeError (str , type (item ))
@@ -228,6 +236,11 @@ def function_to_convert_one_item(
228
236
key_converter = function_to_convert_one_item (inner_types [0 ], json_parser )
229
237
value_converter = function_to_convert_one_item (inner_types [1 ], json_parser )
230
238
return lambda mapping : convert_dict (key_converter , value_converter , mapping ) # type: ignore[arg-type]
239
+ elif is_type_Enum (f_type ):
240
+ if not hasattr (f_type , "_streamable_proxy" ):
241
+ raise UnsupportedType (f"Using Enum ({ f_type } ) in streamable requires a 'streamable_enum' wrapper." )
242
+ convert_func = function_to_convert_one_item (f_type ._streamable_proxy , json_parser )
243
+ return lambda enum : convert_enum (convert_func , enum ) # type: ignore[arg-type]
231
244
elif hasattr (f_type , "from_json_dict" ):
232
245
if json_parser is None :
233
246
json_parser = f_type .from_json_dict
@@ -277,6 +290,11 @@ def function_to_post_init_process_one_item(f_type: type[object]) -> ConvertFunct
277
290
key_converter = function_to_post_init_process_one_item (inner_types [0 ])
278
291
value_converter = function_to_post_init_process_one_item (inner_types [1 ])
279
292
return lambda mapping : convert_dict (key_converter , value_converter , mapping ) # type: ignore[arg-type]
293
+ if is_type_Enum (f_type ):
294
+ if not hasattr (f_type , "_streamable_proxy" ):
295
+ raise UnsupportedType (f"Using Enum ({ f_type } ) in streamable requires a 'streamable_enum' wrapper." )
296
+ process_inner_func = function_to_post_init_process_one_item (f_type ._streamable_proxy )
297
+ return lambda item : convert_enum (f_type ._streamable_proxy , item ) # type: ignore[arg-type]
280
298
return lambda item : post_init_process_item (f_type , item )
281
299
282
300
@@ -307,11 +325,10 @@ def recurse_jsonify(
307
325
val , None , ** next_recursion_env
308
326
)
309
327
return new_dict
310
-
328
+ elif isinstance (d , Enum ):
329
+ return next_recursion_step (d .value , None , ** next_recursion_env )
311
330
elif issubclass (type (d ), bytes ):
312
331
return f"0x{ bytes (d ).hex ()} "
313
- elif isinstance (d , Enum ):
314
- return d .name
315
332
elif isinstance (d , bool ):
316
333
return d
317
334
elif isinstance (d , int ):
@@ -439,6 +456,10 @@ def function_to_parse_one_item(f_type: type[Any]) -> ParseFunctionType:
439
456
key_parse_inner_type_f = function_to_parse_one_item (inner_types [0 ])
440
457
value_parse_inner_type_f = function_to_parse_one_item (inner_types [1 ])
441
458
return lambda f : parse_dict (f , key_parse_inner_type_f , value_parse_inner_type_f )
459
+ if is_type_Enum (f_type ):
460
+ if not hasattr (f_type , "_streamable_proxy" ):
461
+ raise UnsupportedType (f"Using Enum ({ f_type } ) in streamable requires a 'streamable_enum' wrapper." )
462
+ return function_to_parse_one_item (f_type ._streamable_proxy )
442
463
if f_type is str :
443
464
return parse_str
444
465
raise UnsupportedType (f"Type { f_type } does not have parse" )
@@ -529,6 +550,10 @@ def function_to_stream_one_item(f_type: type[Any]) -> StreamFunctionType:
529
550
key_stream_inner_type_func = function_to_stream_one_item (inner_types [0 ])
530
551
value_stream_inner_type_func = function_to_stream_one_item (inner_types [1 ])
531
552
return lambda item , f : stream_dict (key_stream_inner_type_func , value_stream_inner_type_func , item , f )
553
+ elif is_type_Enum (f_type ):
554
+ if not hasattr (f_type , "_streamable_proxy" ):
555
+ raise UnsupportedType (f"Using Enum ({ f_type } ) in streamable requires a 'streamable_enum' wrapper." )
556
+ return function_to_stream_one_item (f_type ._streamable_proxy )
532
557
elif f_type is str :
533
558
return stream_str
534
559
elif f_type is bool :
@@ -700,3 +725,15 @@ class UInt32Range(Streamable):
700
725
class UInt64Range (Streamable ):
701
726
start : uint64 = uint64 (0 )
702
727
stop : uint64 = uint64 .MAXIMUM
728
+
729
+
730
+ _T_Enum = TypeVar ("_T_Enum" , bound = EnumType )
731
+
732
+
733
+ def streamable_enum (proxy : type [Any ]) -> Callable [[_T_Enum ], _T_Enum ]:
734
+ def streamable_enum_wrapper (cls : _T_Enum ) -> _T_Enum :
735
+ setattr (cls , "_streamable_proxy" , proxy )
736
+ setattr (cls , "_ignore_" , ["_streamable_proxy" ])
737
+ return cls
738
+
739
+ return streamable_enum_wrapper
0 commit comments