@@ -17,7 +17,7 @@ pub struct RpcRequest {
1717 pub method : String ,
1818
1919 /// The parameters for the method, as an array of json values.
20- pub params : Vec < Value > ,
20+ pub params : Option < Value > ,
2121
2222 /// An optional identifier for the request, which can be used to match responses.
2323 pub id : Value ,
@@ -27,83 +27,34 @@ pub struct RpcRequest {
2727/// methods already handle the case where the parameter is missing or has an
2828/// unexpected type, returning an error if so.
2929pub mod arg_parser {
30- use std:: str:: FromStr ;
3130
31+ use serde:: Deserialize ;
3232 use serde_json:: Value ;
3333
3434 use crate :: json_rpc:: res:: jsonrpc_interface:: JsonRpcError ;
3535
36- /// Extracts a u64 parameter from the request parameters at the specified index.
37- ///
38- /// This function checks if the parameter exists, is of type u64 and can be converted to `T`.
39- /// Returns an error otherwise.
40- pub fn get_numeric < T : TryFrom < u64 > > (
41- params : & [ Value ] ,
42- index : usize ,
43- opt_name : & str ,
44- ) -> Result < T , JsonRpcError > {
45- let v = params
46- . get ( index)
47- . ok_or_else ( || JsonRpcError :: MissingParameter ( opt_name. to_string ( ) ) ) ?;
48-
49- let n = v. as_u64 ( ) . ok_or_else ( || {
50- JsonRpcError :: InvalidParameterType ( format ! ( "{opt_name} must be a number" ) )
51- } ) ?;
52-
53- T :: try_from ( n)
54- . map_err ( |_| JsonRpcError :: InvalidParameterType ( format ! ( "{opt_name} is out-of-range" ) ) )
55- }
56-
57- /// Extracts a string parameter from the request parameters at the specified index.
58- ///
59- /// This function checks if the parameter exists and is of type string. Returns an error
60- /// otherwise.
61- pub fn get_string (
62- params : & [ Value ] ,
63- index : usize ,
64- opt_name : & str ,
65- ) -> Result < String , JsonRpcError > {
66- let v = params
67- . get ( index)
68- . ok_or_else ( || JsonRpcError :: MissingParameter ( opt_name. to_string ( ) ) ) ?;
69-
70- let str = v. as_str ( ) . ok_or_else ( || {
71- JsonRpcError :: InvalidParameterType ( format ! ( "{opt_name} must be a string" ) )
72- } ) ?;
73-
74- Ok ( str. to_string ( ) )
75- }
76-
77- /// Extracts a boolean parameter from the request parameters at the specified index.
78- ///
79- /// This function checks if the parameter exists and is of type boolean. Returns an error
80- /// otherwise.
81- pub fn get_bool ( params : & [ Value ] , index : usize , opt_name : & str ) -> Result < bool , JsonRpcError > {
82- let v = params
83- . get ( index)
84- . ok_or_else ( || JsonRpcError :: MissingParameter ( opt_name. to_string ( ) ) ) ?;
85-
86- v. as_bool ( ) . ok_or_else ( || {
87- JsonRpcError :: InvalidParameterType ( format ! ( "{opt_name} must be a boolean" ) )
88- } )
89- }
90-
91- /// Extracts a hash parameter from the request parameters at the specified index.
36+ /// Extracts a parameter from the request parameters at the specified index.
9237 ///
9338 /// This function can extract any type that implements `FromStr`, such as `BlockHash` or
9439 /// `Txid`. It checks if the parameter exists and is a valid string representation of the type.
9540 /// Returns an error otherwise.
96- pub fn get_hash < T : FromStr > (
97- params : & [ Value ] ,
41+ pub fn get_at < T : Deserialize < ' static > > (
42+ params : & Value ,
9843 index : usize ,
99- opt_name : & str ,
44+ field_name : & str ,
10045 ) -> Result < T , JsonRpcError > {
101- let v = params
102- . get ( index)
103- . ok_or_else ( || JsonRpcError :: MissingParameter ( opt_name. to_string ( ) ) ) ?;
104-
105- v. as_str ( ) . and_then ( |s| s. parse ( ) . ok ( ) ) . ok_or_else ( || {
106- JsonRpcError :: InvalidParameterType ( format ! ( "{opt_name} must be a valid hash" ) )
46+ let v = match ( params. is_array ( ) , params. is_object ( ) ) {
47+ ( true , false ) => params. get ( index) ,
48+ ( false , true ) => params. get ( field_name) ,
49+ _ => None ,
50+ } ;
51+
52+ let unwrap = v
53+ . ok_or_else ( || JsonRpcError :: MissingParameter ( field_name. to_string ( ) ) ) ?
54+ . clone ( ) ;
55+
56+ T :: deserialize ( unwrap) . map_err ( |_| {
57+ JsonRpcError :: InvalidParameterType ( format ! ( "{field_name} has an invalid type" ) )
10758 } )
10859 }
10960
@@ -112,45 +63,52 @@ pub mod arg_parser {
11263 /// This function can extract an array of any type that implements `FromStr`, such as
11364 /// `BlockHash` or `Txid`. It checks if the parameter exists and is an array of valid string
11465 /// representations of the type. Returns an error otherwise.
115- pub fn get_hashes_array < T : FromStr > (
116- params : & [ Value ] ,
66+ pub fn get_arr_at < T : Deserialize < ' static > > (
67+ params : & Value ,
11768 index : usize ,
118- opt_name : & str ,
69+ field_name : & str ,
11970 ) -> Result < Vec < T > , JsonRpcError > {
120- let v = params
121- . get ( index)
122- . ok_or_else ( || JsonRpcError :: MissingParameter ( opt_name. to_string ( ) ) ) ?;
123-
124- let array = v. as_array ( ) . ok_or_else ( || {
125- JsonRpcError :: InvalidParameterType ( format ! ( "{opt_name} must be an array of hashes" ) )
126- } ) ?;
127-
128- array
71+ let v = match ( params. is_array ( ) , params. is_object ( ) ) {
72+ ( true , false ) => params. get ( index) ,
73+ ( false , true ) => return Err ( JsonRpcError :: InvalidRequest ) ,
74+ _ => None ,
75+ } ;
76+
77+ let unwrap = v
78+ . ok_or_else ( || JsonRpcError :: MissingParameter ( field_name. to_string ( ) ) ) ?
79+ . as_array ( )
80+ . unwrap ( ) ; // Safe unwrap, we checked if this is an array earlier.
81+
82+ unwrap
12983 . iter ( )
130- . map ( |v| {
131- v. as_str ( ) . and_then ( |s| s. parse ( ) . ok ( ) ) . ok_or_else ( || {
132- JsonRpcError :: InvalidParameterType ( format ! ( "{opt_name} must be a valid hash" ) )
133- } )
134- } )
84+ . enumerate ( )
85+ . map ( |( index, v) | get_at ( v, index, field_name) )
13586 . collect ( )
13687 }
13788
138- /// Extracts an optional field from the request parameters at the specified index.
89+ pub fn optional < T > ( result : Result < T , JsonRpcError > ) -> Result < Option < T > , JsonRpcError > {
90+ match result {
91+ Ok ( t) => Ok ( Some ( t) ) ,
92+ Err ( JsonRpcError :: MissingParameter ( _) ) => Ok ( None ) ,
93+ Err ( e) => Err ( e) ,
94+ }
95+ }
96+
97+ /// Extracts a field from the request parameters at the specified index.
13998 ///
14099 /// This function checks if the parameter exists and is of the expected type. If the parameter
141- /// doesn't exist, it returns `None `. If it exists but is of an unexpected type, it returns an
100+ /// doesn't exist, it returns `default `. If it exists but is of an unexpected type, it returns an
142101 /// error.
143- pub fn get_optional_field < T > (
144- params : & [ Value ] ,
102+ pub fn get_with_default < T : Deserialize < ' static > > (
103+ v : & Value ,
145104 index : usize ,
146- opt_name : & str ,
147- extractor_fn : impl Fn ( & [ Value ] , usize , & str ) -> Result < T , JsonRpcError > ,
148- ) -> Result < Option < T > , JsonRpcError > {
149- if params. len ( ) <= index {
150- return Ok ( None ) ;
105+ field_name : & str ,
106+ default : T ,
107+ ) -> Result < T , JsonRpcError > {
108+ match get_at ( v, index, field_name) {
109+ Ok ( t) => Ok ( t) ,
110+ Err ( JsonRpcError :: MissingParameter ( _) ) => Ok ( default) ,
111+ Err ( e) => Err ( e) ,
151112 }
152-
153- let value = extractor_fn ( params, index, opt_name) ?;
154- Ok ( Some ( value) )
155113 }
156114}
0 commit comments