Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for output with both result and error in it #618

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions core-client/transports/src/transports/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,19 @@ pub fn parse_response(
#[serde(deny_unknown_fields)]
#[serde(untagged)]
pub enum ClientResponse {
/// A regular JSON-RPC request output (single response).
/// A regular JSON-RPC 2.0 request output (single response).
Output(jsonrpc_core::Output),
/// A notification.
Notification(jsonrpc_core::Notification),
/// A regular JSON-RPC 1.0 request output (single response).
OutputVersionOne(jsonrpc_core::OutputVersionOne),
}

impl ClientResponse {
/// Get the id of the response (if any).
pub fn id(&self) -> Option<Id> {
match *self {
ClientResponse::OutputVersionOne(ref output) => Some(output.id().clone()),
ClientResponse::Output(ref output) => Some(output.id().clone()),
ClientResponse::Notification(_) => None,
}
Expand All @@ -117,7 +120,7 @@ impl ClientResponse {
pub fn method(&self) -> Option<String> {
match *self {
ClientResponse::Notification(ref n) => Some(n.method.to_owned()),
ClientResponse::Output(_) => None,
ClientResponse::Output(_) | ClientResponse::OutputVersionOne(_) => None,
}
}

Expand All @@ -140,6 +143,7 @@ impl From<ClientResponse> for Result<Value, Error> {
fn from(res: ClientResponse) -> Self {
match res {
ClientResponse::Output(output) => output.into(),
ClientResponse::OutputVersionOne(output) => output.into(),
ClientResponse::Notification(n) => match &n.params {
Params::Map(map) => {
let subscription = map.get("subscription");
Expand Down
2 changes: 1 addition & 1 deletion core/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ pub use self::error::{Error, ErrorCode};
pub use self::id::Id;
pub use self::params::Params;
pub use self::request::{Call, MethodCall, Notification, Request};
pub use self::response::{Failure, Output, Response, Success};
pub use self::response::{Failure, Output, OutputVersionOne, Response, Success};
pub use self::version::Version;
83 changes: 83 additions & 0 deletions core/src/types/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,57 @@ impl From<Output> for CoreResult<Value> {
}
}

/// Represents JSON-RPC v1.x output - failure or success
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct OutputVersionOne {
/// Result
pub result: Option<Value>,
/// Error
pub error: Option<Error>,
/// Correlation id
pub id: Id,
}

impl OutputVersionOne {
/// Creates new output given `Result`, `Id` and `Version`.
pub fn from(result: CoreResult<Value>, id: Id) -> Self {
match result {
Ok(result) => OutputVersionOne {
id,
result: Some(result),
error: None,
},
Err(error) => OutputVersionOne {
id,
error: Some(error),
result: None,
},
}
}

/// Creates new failure output indicating malformed request.
pub fn invalid_request(id: Id) -> Self {
OutputVersionOne {
id,
error: Some(Error::new(ErrorCode::InvalidRequest)),
result: None,
}
}

/// Get the correlation id.
pub fn id(&self) -> &Id {
&self.id
}
}

impl From<OutputVersionOne> for CoreResult<Value> {
/// Convert into a result. Will be `Ok` if `result` is `Some` and `Err` if `result` is `None`.
fn from(output: OutputVersionOne) -> CoreResult<Value> {
output.result.ok_or(output.error.unwrap_or(Error::parse_error()))
}
}

/// Synchronous response
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
Expand Down Expand Up @@ -145,6 +196,20 @@ fn success_output_serialize() {
assert_eq!(serialized, r#"{"jsonrpc":"2.0","result":1,"id":1}"#);
}

#[test]
fn success_output_serialize_1point0() {
use serde_json::Value;

let so = OutputVersionOne {
result: Some(Value::from(1)),
error: None,
id: Id::Num(1),
};

let serialized = serde_json::to_string(&so).unwrap();
assert_eq!(serialized, r#"{"result":1,"error":null,"id":1}"#);
}

#[test]
fn success_output_deserialize() {
use serde_json;
Expand Down Expand Up @@ -232,6 +297,24 @@ fn single_response_deserialize() {
);
}

#[test]
fn single_response_deserialize_1point0() {
use serde_json;
use serde_json::Value;

let dsr = r#"{"result":1,"error":null,"id":1}"#;

let deserialized: OutputVersionOne = serde_json::from_str(dsr).unwrap();
assert_eq!(
deserialized,
OutputVersionOne {
result: Some(Value::from(1)),
error: None,
id: Id::Num(1)
}
);
}

#[test]
fn batch_response_deserialize() {
use serde_json;
Expand Down