Skip to content

Commit

Permalink
Fix abci::Code parser to accept a string or an int
Browse files Browse the repository at this point in the history
Addresses issue informalsystems#10
Added tests for both cases

Signed-off-by: amanusk <amanusk@protonmail.com>
  • Loading branch information
amanusk committed Aug 14, 2019
1 parent 566dfb6 commit a3ae5c8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
50 changes: 39 additions & 11 deletions src/abci/code.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Visitor};
use serde::{Serialize, Serializer};
use std::fmt;

/// ABCI application response codes.
///
Expand Down Expand Up @@ -54,18 +56,44 @@ impl From<Code> for u32 {
}
}

impl<'de> Deserialize<'de> for Code {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Code::from(
String::deserialize(deserializer)?
.parse::<u32>()
.map_err(|e| D::Error::custom(format!("{}", e)))?,
))
}
}

impl Serialize for Code {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.value().serialize(serializer)
}
}

impl<'de> Deserialize<'de> for Code {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct CodeVisitor;

impl<'de> Visitor<'de> for CodeVisitor {
type Value = Code;

fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.write_str("integer or string")
}

fn visit_u64<E>(self, val: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Code::from(val as u32))
}

fn visit_str<E>(self, val: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match val.parse::<u32>() {
Ok(val) => self.visit_u32(val),
Err(_) => Err(E::custom("failed to parse integer")),
}
}
}

deserializer.deserialize_any(CodeVisitor)
}
}
18 changes: 18 additions & 0 deletions tests/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#[cfg(feature = "rpc")]
mod endpoints {
use std::{fs, path::PathBuf};
use tendermint::abci::Code;
use tendermint::rpc::{self, endpoint, Response};

const EXAMPLE_APP: &str = "GaiaApp";
Expand Down Expand Up @@ -122,6 +123,23 @@ mod endpoints {
))
.unwrap();

assert_eq!(response.code, Code::Ok);

assert_eq!(
&response.hash.to_string(),
"0D33F2F03A5234F38706E43004489E061AC40A2E"
);
}

#[test]
fn broadcast_tx_sync_int() {
let response = endpoint::broadcast::tx_sync::Response::from_json(&read_json_fixture(
"broadcast_tx_sync_int",
))
.unwrap();

assert_eq!(response.code, Code::Ok);

assert_eq!(
&response.hash.to_string(),
"0D33F2F03A5234F38706E43004489E061AC40A2E"
Expand Down
10 changes: 10 additions & 0 deletions tests/support/rpc/broadcast_tx_sync_int.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"jsonrpc": "2.0",
"id": "",
"result": {
"code": 0,
"data": "",
"log": "",
"hash": "0D33F2F03A5234F38706E43004489E061AC40A2E"
}
}

0 comments on commit a3ae5c8

Please sign in to comment.