@@ -380,6 +380,70 @@ def Vec(T):
380
380
raise NotSupported ()
381
381
382
382
383
+ @six .python_2_unicode_compatible
384
+ class Opt (ExonumSegment ):
385
+ def __init__ (self , * val ):
386
+ if len (val ) == 0 :
387
+ self ._set_order ()
388
+ return
389
+
390
+ val = val [0 ]
391
+ if val :
392
+ if isinstance (val , self .T ):
393
+ self .val = val
394
+ else :
395
+ self .val = self .T (val )
396
+ else :
397
+ self .val = None
398
+
399
+ def count (self ):
400
+ return 1 if self .val else 0
401
+
402
+ def __str__ (self ):
403
+ v = self .val
404
+ repr = "{}" .format (v ) if v else "None"
405
+ return "{} [{}]" .format (self .__class__ .__name__ , ", " .join (repr ))
406
+
407
+ @classmethod
408
+ def read_buffer (cls , buf , offset = 0 , cnt = 0 ):
409
+ dbg ("reading Opt of sz {}" .format (cnt ))
410
+ if cnt == 1 :
411
+ t = cls .T .read (buf , offset = offset )
412
+ dbg ("read {} at offset {}" .format (t , offset ))
413
+ return cls (t )
414
+ else :
415
+ assert cnt == 0 , "One argument expected"
416
+ return cls (None )
417
+
418
+ def write (self , buf , offset ):
419
+ dbg (
420
+ "writing Opt ({}) of sz {} at offset {}" .format (
421
+ self .T .__name__ , self .count (), offset
422
+ )
423
+ )
424
+ buf [offset : offset + self .sz ] = struct .pack (self .fmt , len (buf ), self .count ())
425
+ self .extend_buffer (buf )
426
+
427
+ def extend_buffer (self , buf ):
428
+ offset = len (buf )
429
+ buf += bytearray (self .count () * self .T .sz )
430
+ if self .val :
431
+ self .val .write (buf , offset )
432
+ offset += self .T .sz
433
+
434
+ def plain (self ):
435
+ if self .val :
436
+ return self .val .plain ()
437
+ else :
438
+ return None
439
+
440
+
441
+ def Option (T ):
442
+ if issubclass (T , ExonumField ):
443
+ return type ("Option<{}>" .format (T .__name__ ), (Opt ,), {"T" : T })()
444
+ raise NotSupported ()
445
+
446
+
383
447
class ExonumBase (ExonumSegment ):
384
448
def count (self ):
385
449
return self .cnt
0 commit comments