@@ -24,6 +24,8 @@ use hashes::sha256d;
2424use internals:: compact_size;
2525#[ cfg( feature = "hex" ) ]
2626use internals:: write_err;
27+ #[ cfg( feature = "serde" ) ]
28+ use serde:: { de, Deserialize , Deserializer , Serialize , Serializer } ;
2729#[ cfg( feature = "hex" ) ]
2830use units:: parse_int;
2931
@@ -357,8 +359,6 @@ pub struct OutPoint {
357359 /// The index of the referenced output in its transaction's vout.
358360 pub vout : u32 ,
359361}
360- #[ cfg( feature = "serde" ) ]
361- internals:: serde_struct_human_string_impl!( OutPoint , "an OutPoint" , txid, vout) ;
362362
363363impl OutPoint {
364364 /// The number of bytes that an outpoint contributes to the size of a transaction.
@@ -419,6 +419,120 @@ fn parse_vout(s: &str) -> Result<u32, ParseOutPointError> {
419419 parse_int:: int_from_str ( s) . map_err ( ParseOutPointError :: Vout )
420420}
421421
422+ #[ cfg( feature = "serde" ) ]
423+ impl Serialize for OutPoint {
424+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
425+ where
426+ S : Serializer ,
427+ {
428+ if serializer. is_human_readable ( ) {
429+ serializer. collect_str ( & self )
430+ } else {
431+ use crate :: serde:: ser:: SerializeStruct as _;
432+
433+ let mut state = serializer. serialize_struct ( "OutPoint" , 2 ) ?;
434+ // serializing as an array was found in the past to break for some serializers so we use
435+ // a slice instead. This causes 8 bytes to be prepended for the length (even though this
436+ // is a bit silly because know the length).
437+ state. serialize_field ( "txid" , self . txid . as_byte_array ( ) . as_slice ( ) ) ?;
438+ state. serialize_field ( "vout" , & self . vout . to_le_bytes ( ) ) ?;
439+ state. end ( )
440+ }
441+ }
442+ }
443+
444+ #[ cfg( feature = "serde" ) ]
445+ impl < ' de > Deserialize < ' de > for OutPoint {
446+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
447+ where
448+ D : Deserializer < ' de > ,
449+ {
450+ if deserializer. is_human_readable ( ) {
451+ struct StringVisitor ;
452+
453+ impl < ' de > de:: Visitor < ' de > for StringVisitor {
454+ type Value = OutPoint ;
455+
456+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
457+ formatter. write_str ( "a string in format 'txid:vout'" )
458+ }
459+
460+ fn visit_str < E > ( self , value : & str ) -> Result < OutPoint , E >
461+ where
462+ E : de:: Error ,
463+ {
464+ value. parse :: < OutPoint > ( ) . map_err ( de:: Error :: custom)
465+ }
466+ }
467+
468+ deserializer. deserialize_str ( StringVisitor )
469+ } else {
470+ #[ derive( Deserialize ) ]
471+ #[ serde( field_identifier, rename_all = "lowercase" ) ]
472+ enum Field {
473+ Txid ,
474+ Vout ,
475+ }
476+
477+ struct OutPointVisitor ;
478+
479+ impl < ' de > de:: Visitor < ' de > for OutPointVisitor {
480+ type Value = OutPoint ;
481+
482+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
483+ formatter. write_str ( "OutPoint struct with fields" )
484+ }
485+
486+ fn visit_seq < V > ( self , mut seq : V ) -> Result < OutPoint , V :: Error >
487+ where
488+ V : de:: SeqAccess < ' de > ,
489+ {
490+ let txid =
491+ seq. next_element ( ) ?. ok_or_else ( || de:: Error :: invalid_length ( 0 , & self ) ) ?;
492+ let vout =
493+ seq. next_element ( ) ?. ok_or_else ( || de:: Error :: invalid_length ( 1 , & self ) ) ?;
494+ Ok ( OutPoint { txid, vout } )
495+ }
496+
497+ fn visit_map < V > ( self , mut map : V ) -> Result < OutPoint , V :: Error >
498+ where
499+ V : de:: MapAccess < ' de > ,
500+ {
501+ let mut txid = None ;
502+ let mut vout = None ;
503+
504+ while let Some ( key) = map. next_key ( ) ? {
505+ match key {
506+ Field :: Txid => {
507+ if txid. is_some ( ) {
508+ return Err ( de:: Error :: duplicate_field ( "txid" ) ) ;
509+ }
510+ let bytes: [ u8 ; 32 ] = map. next_value ( ) ?;
511+ txid = Some ( Txid :: from_byte_array ( bytes) ) ;
512+ }
513+ Field :: Vout => {
514+ if vout. is_some ( ) {
515+ return Err ( de:: Error :: duplicate_field ( "vout" ) ) ;
516+ }
517+ let bytes: [ u8 ; 4 ] = map. next_value ( ) ?;
518+ vout = Some ( u32:: from_le_bytes ( bytes) ) ;
519+ }
520+ }
521+ }
522+
523+ let txid = txid. ok_or_else ( || de:: Error :: missing_field ( "txid" ) ) ?;
524+ let vout = vout. ok_or_else ( || de:: Error :: missing_field ( "vout" ) ) ?;
525+
526+ Ok ( OutPoint { txid, vout } )
527+ }
528+ }
529+
530+ const FIELDS : & [ & str ] = & [ "txid" , "vout" ] ;
531+ deserializer. deserialize_struct ( "OutPoint" , FIELDS , OutPointVisitor )
532+ }
533+ }
534+ }
535+
422536/// An error in parsing an [`OutPoint`].
423537#[ derive( Debug , Clone , PartialEq , Eq ) ]
424538#[ non_exhaustive]
0 commit comments