Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Accept also None or Objects as params #108

Merged
merged 5 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 0.17.0 - 2023-06-29
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Perhaps use "unreleased" so we don't forget to update the header when doing the release.

Suggested change
# 0.17.0 - 2023-06-29
# unreleased


* `params` field in `Request` changed to a generic `RawValue` instead of an array.
[#108](https://github.com/apoelstra/rust-jsonrpc/pull/108)

# 0.16.0 - 2023-06-29

* Re-export the `minreq` crate when the feature is set
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn client(url: &str, user: &str, pass: &str) -> Result<Client, simple_http::Erro
// Demonstrate an example JSON-RCP call against bitcoind.
fn main() {
let client = client("localhost:18443", "user", "pass").expect("failed to create client");
let request = client.build_request("uptime", &[]);
let request = client.build_request("uptime", None);
let response = client.send_request(request).expect("send_request failed");

// For other commands this would be a struct matching the returned json.
Expand Down
4 changes: 4 additions & 0 deletions contrib/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ fi
# Pin dependencies as required if we are using MSRV toolchain.
if cargo --version | grep "1\.48"; then
# 1.0.157 uses syn 2.0 which requires edition 2021
cargo update -p serde_json --precise 1.0.99
cargo update -p serde --precise 1.0.156
cargo update -p quote --precise 1.0.30
cargo update -p proc-macro2 --precise 1.0.63
cargo update -p byteorder --precise 1.4.3
fi

# Make all cargo invocations verbose
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/minreq_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn do_test(data: &[u8]) {
.build();

let client = Client::with_transport(t);
let request = client.build_request("uptime", &[]);
let request = client.build_request("uptime", None);
let _ = client.send_request(request);
}
}
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/simple_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn do_test(data: &[u8]) {
.build();

let client = Client::with_transport(t);
let request = client.build_request("uptime", &[]);
let request = client.build_request("uptime", None);
let _ = client.send_request(request);
}
}
Expand Down
43 changes: 42 additions & 1 deletion integration_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ use backtrace::Backtrace;

use jsonrpc::http::minreq_http;
use jsonrpc::{Client, Request};
use serde_json::json;
use serde_json::value::to_raw_value;

struct StdLogger;

Expand Down Expand Up @@ -113,6 +115,9 @@ fn main() {

run_test!(test_get_network_info);

run_test!(test_get_block_hash_list);
run_test!(test_get_block_hash_named);

// Print results
println!("");
println!("");
Expand Down Expand Up @@ -140,10 +145,46 @@ fn main() {
fn test_get_network_info(cl: &Client) {
let request = Request {
method: "getnetworkinfo".into(),
params: &[],
params: None,
id: serde_json::json!(1),
jsonrpc: Some("2.0"),
};

let _ = cl.send_request(request).unwrap();
}

fn test_get_block_hash_list(cl: &Client) {
let param = json!([0]);
let raw_value = Some(to_raw_value(&param).unwrap());

let request = Request {
method: "getblockhash".into(),
params: raw_value.as_deref(),
id: serde_json::json!(2),
jsonrpc: Some("2.0"),
};

let resp = cl.send_request(request).unwrap();
assert_eq!(
resp.result.unwrap().to_string(),
"\"0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206\""
);
}

fn test_get_block_hash_named(cl: &Client) {
let param = json!({ "height": 0 });
let raw_value = Some(to_raw_value(&param).unwrap());

let request = Request {
method: "getblockhash".into(),
params: raw_value.as_deref(),
id: serde_json::json!(2),
jsonrpc: Some("2.0"),
};

let resp = cl.send_request(request).unwrap();
assert_eq!(
resp.result.unwrap().to_string(),
"\"0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206\""
);
}
8 changes: 4 additions & 4 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl Client {
///
/// To construct the arguments, one can use one of the shorthand methods
/// [`crate::arg`] or [`crate::try_arg`].
pub fn build_request<'a>(&self, method: &'a str, params: &'a [Box<RawValue>]) -> Request<'a> {
pub fn build_request<'a>(&self, method: &'a str, params: Option<&'a RawValue>) -> Request<'a> {
let nonce = self.nonce.fetch_add(1, atomic::Ordering::Relaxed);
Request {
method,
Expand Down Expand Up @@ -115,7 +115,7 @@ impl Client {
pub fn call<R: for<'a> serde::de::Deserialize<'a>>(
&self,
method: &str,
args: &[Box<RawValue>],
args: Option<&RawValue>,
) -> Result<R, Error> {
let request = self.build_request(method, args);
let id = request.id.clone();
Expand Down Expand Up @@ -224,9 +224,9 @@ mod tests {
fn sanity() {
let client = Client::with_transport(DummyTransport);
assert_eq!(client.nonce.load(sync::atomic::Ordering::Relaxed), 1);
let req1 = client.build_request("test", &[]);
let req1 = client.build_request("test", None);
assert_eq!(client.nonce.load(sync::atomic::Ordering::Relaxed), 2);
let req2 = client.build_request("test", &[]);
let req2 = client.build_request("test", None);
assert_eq!(client.nonce.load(sync::atomic::Ordering::Relaxed), 3);
assert!(req1.id != req2.id);
}
Expand Down
4 changes: 2 additions & 2 deletions src/http/simple_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -818,11 +818,11 @@ mod tests {
let port = rx.recv().unwrap();
let client =
Client::simple_http(format!("localhost:{}", port).as_str(), None, None).unwrap();
let request = client.build_request("test_request", &[]);
let request = client.build_request("test_request", None);
let result = client.send_request(request).unwrap();
assert_eq!(result.id, Value::Number(Number::from(0)));
thread::sleep(Duration::from_secs(1));
let request = client.build_request("test_request2", &[]);
let request = client.build_request("test_request2", None);
let result2 = client.send_request(request)
.expect("This second request should not be an Err like `Err(Transport(HttpResponseTooShort { actual: 0, needed: 12 }))`");
assert_eq!(result2.id, Value::Number(Number::from(1)));
Expand Down
41 changes: 39 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub struct Request<'a> {
/// The name of the RPC call.
pub method: &'a str,
/// Parameters to the RPC call.
pub params: &'a [Box<RawValue>],
pub params: Option<&'a RawValue>,
/// Identifier for this request, which should appear in the response.
pub id: serde_json::Value,
/// jsonrpc field, MUST be "2.0".
Expand Down Expand Up @@ -123,7 +123,10 @@ impl Response {
mod tests {
use super::*;

use serde_json::value::RawValue;
use serde_json::{
json,
value::{to_raw_value, RawValue},
};

#[test]
fn response_is_none() {
Expand Down Expand Up @@ -219,4 +222,38 @@ mod tests {
Test
);
}

#[test]
fn test_request_list() {
let list = json!([0]);
let raw_value = Some(to_raw_value(&list).unwrap());

let request = Request {
method: "list",
params: raw_value.as_deref(),
id: serde_json::json!(2),
jsonrpc: Some("2.0"),
};
assert_eq!(
serde_json::to_string(&request).unwrap(),
r#"{"method":"list","params":[0],"id":2,"jsonrpc":"2.0"}"#
);
}

#[test]
fn test_request_object() {
let object = json!({ "height": 0 });
let raw_value = Some(to_raw_value(&object).unwrap());

let request = Request {
method: "object",
params: raw_value.as_deref(),
id: serde_json::json!(2),
jsonrpc: Some("2.0"),
};
assert_eq!(
serde_json::to_string(&request).unwrap(),
r#"{"method":"object","params":{"height":0},"id":2,"jsonrpc":"2.0"}"#
);
}
}
2 changes: 1 addition & 1 deletion src/simple_tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ mod tests {
let addr = server.local_addr().unwrap();
let dummy_req = Request {
method: "arandommethod",
params: &[],
params: None,
id: serde_json::Value::Number(4242242.into()),
jsonrpc: Some("2.0"),
};
Expand Down
2 changes: 1 addition & 1 deletion src/simple_uds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ mod tests {
let server = UnixListener::bind(&socket_path).unwrap();
let dummy_req = Request {
method: "getinfo",
params: &[],
params: None,
id: serde_json::Value::Number(111.into()),
jsonrpc: Some("2.0"),
};
Expand Down
Loading