Skip to content

Commit

Permalink
Serde Protojson support (#166)
Browse files Browse the repository at this point in the history
* Add protobuild support

* In progress

* update compile.rs

* working example

* in progress

* update deps

* Add eq/ord type attrs back

* Using informal pbjson fork

* Re-add json schema

* Emit default fields

* Update changelog

* Add FungibleTokenPacketData test
  • Loading branch information
grod220 authored Dec 28, 2023
1 parent 9c8be3d commit 419e3a3
Show file tree
Hide file tree
Showing 81 changed files with 72,500 additions and 1,041 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added protojson support
([#166](https://github.com/cosmos/ibc-proto-rs/pull/166)). Feature flag `serde` now abides by [protobuf json rules](https://protobuf.dev/programming-guides/proto3/#json) when it comes to json serialization/deserialization.
24 changes: 14 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ doctest = false
all-features = true

[dependencies]
prost = { version = "0.12.3", default-features = false, features = ["prost-derive"] }
bytes = { version = "1.2", default-features = false }
tonic = { version = "0.10", default-features = false, optional = true }
serde = { version = "1.0", default-features = false, optional = true }
schemars = { version = "0.8", optional = true }
subtle-encoding = { version = "0.5", default-features = false }
base64 = { version = "0.21", default-features = false, features = ["alloc"] }
flex-error = { version = "0.4", default-features = false }
ics23 = { version = "0.11.0", default-features = false }
prost = { version = "0.12.3", default-features = false, features = ["prost-derive"] }
bytes = { version = "1.2", default-features = false }
tonic = { version = "0.10", default-features = false, optional = true }
serde = { version = "1.0", default-features = false, optional = true }
schemars = { version = "0.8", optional = true }
subtle-encoding = { version = "0.5", default-features = false }
base64 = { version = "0.21", default-features = false, features = ["alloc"] }
flex-error = { version = "0.4", default-features = false }
ics23 = { version = "0.11.0", default-features = false }
informalsystems-pbjson = { version = "0.6.0", optional = true, default-features = false }

## Optional: enabled by the `parity-scale-codec` feature
parity-scale-codec = { version = "3.0.0", default-features = false, features = ["full"], optional = true }
Expand All @@ -50,10 +51,13 @@ borsh = { version = "0.10", default-features = false, optional = true }
version = "0.34"
default-features = false

[dev-dependencies]
serde_json = "1.0.107"

[features]
default = ["std", "client"]
std = ["prost/std", "bytes/std", "subtle-encoding/std", "base64/std", "flex-error/std", "ics23/std"]
serde = ["dep:serde", "ics23/serde"]
serde = ["dep:serde", "ics23/serde", "informalsystems-pbjson"]
client = ["std", "dep:tonic", "tonic/codegen", "tonic/transport", "tonic/prost"]
json-schema = ["std", "serde", "dep:schemars"]
server = ["std", "dep:tonic", "tonic/codegen", "tonic/transport", "tonic/prost"]
Expand Down
2 changes: 2 additions & 0 deletions src/google.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub mod protobuf {
use crate::include_proto;
include_proto!("google.protobuf.rs");
#[cfg(feature = "serde")]
include_proto!("google.protobuf.serde.rs");

// source: https://github.com/tokio-rs/prost/blob/master/prost-types/src/lib.rs
use core::convert::TryFrom;
Expand Down
115 changes: 90 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
// Todo: automate the creation of this module setup based on the dots in the filenames.
// This module setup is necessary because the generated code contains "super::" calls for dependencies.

#![cfg_attr(not(feature = "std"), no_std)]
#![deny(warnings, trivial_casts, trivial_numeric_casts, unused_import_braces)]
#![cfg_attr(
not(feature = "serde"),
deny(warnings, trivial_casts, trivial_numeric_casts, unused_import_braces)
)]
#![allow(clippy::large_enum_variant, clippy::derive_partial_eq_without_eq)]
#![allow(rustdoc::bare_urls)]
#![forbid(unsafe_code)]
Expand Down Expand Up @@ -43,11 +45,15 @@ pub mod cosmos {
pub mod app {
pub mod v1alpha1 {
include_proto!("cosmos.app.v1alpha1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.app.v1alpha1.serde.rs");
}
}
pub mod auth {
pub mod v1beta1 {
include_proto!("cosmos.auth.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.auth.v1beta1.serde.rs");
/// EthAccount defines an Ethermint account.
/// TODO: remove when/if a canonical `EthAccount`
/// lands in the next Cosmos SDK release
Expand All @@ -64,26 +70,36 @@ pub mod cosmos {
pub mod module {
pub mod v1 {
include_proto!("cosmos.auth.module.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.auth.module.v1.serde.rs");
}
}
}
pub mod staking {
pub mod v1beta1 {
include_proto!("cosmos.staking.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.staking.v1beta1.serde.rs");
}
pub mod module {
pub mod v1 {
include_proto!("cosmos.staking.module.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.staking.module.v1.serde.rs");
}
}
}
pub mod bank {
pub mod v1beta1 {
include_proto!("cosmos.bank.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.bank.v1beta1.serde.rs");
}
pub mod module {
pub mod v1 {
include_proto!("cosmos.bank.module.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.bank.module.v1.serde.rs");
}
}
}
Expand All @@ -96,20 +112,28 @@ pub mod cosmos {
pub mod node {
pub mod v1beta1 {
include_proto!("cosmos.base.node.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.base.node.v1beta1.serde.rs");
}
}
pub mod query {
pub mod v1beta1 {
include_proto!("cosmos.base.query.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.base.query.v1beta1.serde.rs");
}
}
pub mod reflection {
pub mod v1beta1 {
include_proto!("cosmos.base.reflection.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.base.reflection.v1beta1.serde.rs");
}
}
pub mod v1beta1 {
include_proto!("cosmos.base.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.base.v1beta1.serde.rs");
}
pub mod tendermint {
pub mod v1beta1 {
Expand All @@ -119,50 +143,72 @@ pub mod cosmos {
pub mod kv {
pub mod v1beta1 {
include_proto!("cosmos.base.kv.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.base.kv.v1beta1.serde.rs");
}
}
pub mod snapshots {
pub mod v1beta1 {
include_proto!("cosmos.base.snapshots.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.base.snapshots.v1beta1.serde.rs");
}
}
}
pub mod crypto {
pub mod multisig {
pub mod v1beta1 {
include_proto!("cosmos.crypto.multisig.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.crypto.multisig.v1beta1.serde.rs");
}
include_proto!("cosmos.crypto.multisig.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.crypto.multisig.serde.rs");
}
pub mod ed25519 {
include_proto!("cosmos.crypto.ed25519.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.crypto.ed25519.serde.rs");
}
pub mod secp256k1 {
include_proto!("cosmos.crypto.secp256k1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.crypto.secp256k1.serde.rs");
}
pub mod secp256r1 {
include_proto!("cosmos.crypto.secp256r1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.crypto.secp256r1.serde.rs");
}
pub mod keyring {
pub mod v1 {
include_proto!("cosmos.crypto.keyring.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.crypto.keyring.v1.serde.rs");
}
}
pub mod hd {
pub mod v1 {
include_proto!("cosmos.crypto.hd.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.crypto.hd.v1.serde.rs");
}
}
}
pub mod tx {
pub mod config {
pub mod v1 {
include_proto!("cosmos.tx.config.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.tx.config.v1.serde.rs");
}
}
pub mod signing {
pub mod v1beta1 {
include_proto!("cosmos.tx.signing.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.tx.signing.v1beta1.serde.rs");
}
}
pub mod v1beta1 {
Expand All @@ -172,23 +218,33 @@ pub mod cosmos {
pub mod upgrade {
pub mod v1beta1 {
include_proto!("cosmos.upgrade.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.upgrade.v1beta1.serde.rs");
}
pub mod module {
pub mod v1 {
include_proto!("cosmos.upgrade.module.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.upgrade.module.v1.serde.rs");
}
}
}
pub mod gov {
pub mod v1 {
include_proto!("cosmos.gov.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.gov.v1.serde.rs");
}
pub mod v1beta1 {
include_proto!("cosmos.gov.v1beta1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.gov.v1beta1.serde.rs");
}
pub mod module {
pub mod v1 {
include_proto!("cosmos.gov.module.v1.rs");
#[cfg(feature = "serde")]
include_proto!("cosmos.gov.module.v1.serde.rs");
}
}
}
Expand All @@ -206,28 +262,40 @@ pub mod ibc {
pub mod transfer {
pub mod v1 {
include_proto!("ibc.applications.transfer.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.applications.transfer.v1.serde.rs");
}
pub mod v2 {
include_proto!("ibc.applications.transfer.v2.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.applications.transfer.v2.serde.rs");
}
}
pub mod fee {
pub mod v1 {
include_proto!("ibc.applications.fee.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.applications.fee.v1.serde.rs");
}
}
pub mod interchain_accounts {
pub mod v1 {
include_proto!("ibc.applications.interchain_accounts.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.applications.interchain_accounts.v1.serde.rs");
}
pub mod controller {
pub mod v1 {
include_proto!("ibc.applications.interchain_accounts.controller.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.applications.interchain_accounts.controller.v1.serde.rs");
}
}
pub mod host {
pub mod v1 {
include_proto!("ibc.applications.interchain_accounts.host.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.applications.interchain_accounts.host.v1.serde.rs");
}
}
}
Expand All @@ -236,51 +304,71 @@ pub mod ibc {
pub mod channel {
pub mod v1 {
include_proto!("ibc.core.channel.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.core.channel.v1.serde.rs");
}
}
pub mod client {
pub mod v1 {
include_proto!("ibc.core.client.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.core.client.v1.serde.rs");
}
}
pub mod commitment {
pub mod v1 {
include_proto!("ibc.core.commitment.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.core.commitment.v1.serde.rs");
}
}
pub mod connection {
pub mod v1 {
include_proto!("ibc.core.connection.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.core.connection.v1.serde.rs");
}
}
pub mod types {
pub mod v1 {
include_proto!("ibc.core.types.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.core.types.v1.serde.rs");
}
}
}
pub mod lightclients {
pub mod localhost {
pub mod v1 {
include_proto!("ibc.lightclients.localhost.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.lightclients.localhost.v1.serde.rs");
}
pub mod v2 {
include_proto!("ibc.lightclients.localhost.v2.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.lightclients.localhost.v2.serde.rs");
}
}
pub mod solomachine {
pub mod v3 {
include_proto!("ibc.lightclients.solomachine.v3.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.lightclients.solomachine.v3.serde.rs");
}
}
pub mod tendermint {
pub mod v1 {
include_proto!("ibc.lightclients.tendermint.v1.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.lightclients.tendermint.v1.serde.rs");
}
}
}
pub mod mock {
include_proto!("ibc.mock.rs");
#[cfg(feature = "serde")]
include_proto!("ibc.mock.serde.rs");
}
}

Expand Down Expand Up @@ -313,26 +401,3 @@ pub mod stride {
}
}
}

#[cfg(feature = "serde")]
pub(crate) mod base64 {
use alloc::string::String;
use alloc::vec::Vec;

use base64::prelude::*;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
let encoded = BASE64_STANDARD.encode(bytes);
String::serialize(&encoded, serializer)
}

pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
let base64 = String::deserialize(deserializer)?;
let bytes = BASE64_STANDARD
.decode(base64.as_bytes())
.map_err(serde::de::Error::custom)?;

Ok(bytes)
}
}
Loading

0 comments on commit 419e3a3

Please sign in to comment.