@@ -4,7 +4,7 @@ use crate::utils::hex_to_uint256;
4
4
5
5
use bitcoin:: blockdata:: block:: { Block , BlockHeader } ;
6
6
use bitcoin:: consensus:: encode;
7
- use bitcoin:: hash_types:: { BlockHash , TxMerkleNode } ;
7
+ use bitcoin:: hash_types:: { BlockHash , TxMerkleNode , Txid } ;
8
8
use bitcoin:: hashes:: hex:: { ToHex , FromHex } ;
9
9
10
10
use serde:: Deserialize ;
@@ -156,11 +156,37 @@ impl TryInto<(BlockHash, Option<u32>)> for JsonResponse {
156
156
}
157
157
}
158
158
159
+ impl TryInto < Txid > for JsonResponse {
160
+ type Error = std:: io:: Error ;
161
+ fn try_into ( self ) -> std:: io:: Result < Txid > {
162
+ match self . 0 . as_str ( ) {
163
+ None => Err ( std:: io:: Error :: new (
164
+ std:: io:: ErrorKind :: InvalidData ,
165
+ "expected JSON string" ,
166
+ ) ) ,
167
+ Some ( hex_data) => match Vec :: < u8 > :: from_hex ( hex_data) {
168
+ Err ( _) => Err ( std:: io:: Error :: new (
169
+ std:: io:: ErrorKind :: InvalidData ,
170
+ "invalid hex data" ,
171
+ ) ) ,
172
+ Ok ( txid_data) => match encode:: deserialize ( & txid_data) {
173
+ Err ( _) => Err ( std:: io:: Error :: new (
174
+ std:: io:: ErrorKind :: InvalidData ,
175
+ "invalid txid" ,
176
+ ) ) ,
177
+ Ok ( block) => Ok ( block) ,
178
+ } ,
179
+ } ,
180
+ }
181
+ }
182
+ }
183
+
159
184
#[ cfg( test) ]
160
185
pub ( crate ) mod tests {
161
186
use super :: * ;
162
187
use bitcoin:: blockdata:: constants:: genesis_block;
163
188
use bitcoin:: consensus:: encode;
189
+ use bitcoin:: hashes:: Hash ;
164
190
use bitcoin:: network:: constants:: Network ;
165
191
166
192
/// Converts from `BlockHeaderData` into a `GetHeaderResponse` JSON value.
@@ -469,4 +495,50 @@ pub(crate) mod tests {
469
495
} ,
470
496
}
471
497
}
498
+
499
+ #[ test]
500
+ fn into_txid_from_json_response_with_unexpected_type ( ) {
501
+ let response = JsonResponse ( serde_json:: json!( { "result" : "foo" } ) ) ;
502
+ match TryInto :: < Txid > :: try_into ( response) {
503
+ Err ( e) => {
504
+ assert_eq ! ( e. kind( ) , std:: io:: ErrorKind :: InvalidData ) ;
505
+ assert_eq ! ( e. get_ref( ) . unwrap( ) . to_string( ) , "expected JSON string" ) ;
506
+ }
507
+ Ok ( _) => panic ! ( "Expected error" ) ,
508
+ }
509
+ }
510
+
511
+ #[ test]
512
+ fn into_txid_from_json_response_with_invalid_hex_data ( ) {
513
+ let response = JsonResponse ( serde_json:: json!( "foobar" ) ) ;
514
+ match TryInto :: < Txid > :: try_into ( response) {
515
+ Err ( e) => {
516
+ assert_eq ! ( e. kind( ) , std:: io:: ErrorKind :: InvalidData ) ;
517
+ assert_eq ! ( e. get_ref( ) . unwrap( ) . to_string( ) , "invalid hex data" ) ;
518
+ }
519
+ Ok ( _) => panic ! ( "Expected error" ) ,
520
+ }
521
+ }
522
+
523
+ #[ test]
524
+ fn into_txid_from_json_response_with_invalid_txid_data ( ) {
525
+ let response = JsonResponse ( serde_json:: json!( "abcd" ) ) ;
526
+ match TryInto :: < Txid > :: try_into ( response) {
527
+ Err ( e) => {
528
+ assert_eq ! ( e. kind( ) , std:: io:: ErrorKind :: InvalidData ) ;
529
+ assert_eq ! ( e. get_ref( ) . unwrap( ) . to_string( ) , "invalid txid" ) ;
530
+ }
531
+ Ok ( _) => panic ! ( "Expected error" ) ,
532
+ }
533
+ }
534
+
535
+ #[ test]
536
+ fn into_txid_from_json_response_with_valid_txid_data ( ) {
537
+ let target_txid = Txid :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ;
538
+ let response = JsonResponse ( serde_json:: json!( encode:: serialize_hex( & target_txid) ) ) ;
539
+ match TryInto :: < Txid > :: try_into ( response) {
540
+ Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
541
+ Ok ( txid) => assert_eq ! ( txid, target_txid) ,
542
+ }
543
+ }
472
544
}
0 commit comments