Skip to content

Commit

Permalink
Encode claimable balance ids to match Horizon in JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmcculloch committed May 13, 2024
1 parent 72fa91b commit 31890cf
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 8 deletions.
39 changes: 36 additions & 3 deletions src/curr/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
//# - AssetCode
//# - AssetCode4
//# - AssetCode12
#![cfg(feature = "alloc")]
//#
//# ## Other
//# - ClaimableBalanceId
#![cfg(feature = "std")]

use super::{
AccountId, AssetCode, AssetCode12, AssetCode4, Error, Hash, MuxedAccount, MuxedAccountMed25519,
NodeId, PublicKey, ScAddress, SignerKey, SignerKeyEd25519SignedPayload, Uint256,
AccountId, AssetCode, AssetCode12, AssetCode4, ClaimableBalanceId, Error, Hash, Limits,
MuxedAccount, MuxedAccountMed25519, NodeId, PublicKey, ReadXdr, ScAddress, SignerKey,
SignerKeyEd25519SignedPayload, Uint256, WriteXdr,
};

impl From<stellar_strkey::DecodeError> for Error {
Expand Down Expand Up @@ -336,3 +340,32 @@ impl core::fmt::Display for AssetCode {
}
}
}

impl core::str::FromStr for ClaimableBalanceId {
type Err = Error;
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
let bytes = hex::decode(s).map_err(|_| Error::InvalidHex)?;
ClaimableBalanceId::from_xdr(
bytes,
// No limit is safe for encoding ClaimableBalanceId as the type is a
// fixed size type.
Limits::none(),
)
}
}

impl core::fmt::Display for ClaimableBalanceId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let bytes = self
.to_xdr(
// No limit is safe for encoding ClaimableBalanceId as the type is a
// fixed size type.
Limits::none(),
)
.map_err(|_| core::fmt::Error)?;
for b in bytes {
write!(f, "{b:02x}")?;
}
Ok(())
}
}
39 changes: 36 additions & 3 deletions src/next/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
//# - AssetCode
//# - AssetCode4
//# - AssetCode12
#![cfg(feature = "alloc")]
//#
//# ## Other
//# - ClaimableBalanceId
#![cfg(feature = "std")]

use super::{
AccountId, AssetCode, AssetCode12, AssetCode4, Error, Hash, MuxedAccount, MuxedAccountMed25519,
NodeId, PublicKey, ScAddress, SignerKey, SignerKeyEd25519SignedPayload, Uint256,
AccountId, AssetCode, AssetCode12, AssetCode4, ClaimableBalanceId, Error, Hash, Limits,
MuxedAccount, MuxedAccountMed25519, NodeId, PublicKey, ReadXdr, ScAddress, SignerKey,
SignerKeyEd25519SignedPayload, Uint256, WriteXdr,
};

impl From<stellar_strkey::DecodeError> for Error {
Expand Down Expand Up @@ -325,3 +329,32 @@ impl core::fmt::Display for AssetCode {
}
}
}

impl core::str::FromStr for ClaimableBalanceId {
type Err = Error;
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
let bytes = hex::decode(s).map_err(|_| Error::InvalidHex)?;
ClaimableBalanceId::from_xdr(
bytes,
// No limit is safe for encoding ClaimableBalanceId as the type is a
// fixed size type.
Limits::none(),
)
}
}

impl core::fmt::Display for ClaimableBalanceId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let bytes = self
.to_xdr(
// No limit is safe for encoding ClaimableBalanceId as the type is a
// fixed size type.
Limits::none(),
)
.map_err(|_| core::fmt::Error)?;
for b in bytes {
write!(f, "{b:02x}")?;
}
Ok(())
}
}
26 changes: 24 additions & 2 deletions tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
use stellar_xdr::curr as stellar_xdr;

use stellar_xdr::{
AccountId, AssetCode, AssetCode12, AssetCode4, Error, Hash, MuxedAccount, MuxedAccountMed25519,
NodeId, PublicKey, ScAddress, SignerKey, SignerKeyEd25519SignedPayload, Uint256,
AccountId, AssetCode, AssetCode12, AssetCode4, ClaimableBalanceId, Error, Hash, MuxedAccount,
MuxedAccountMed25519, NodeId, PublicKey, ScAddress, SignerKey, SignerKeyEd25519SignedPayload,
Uint256,
};

use std::str::FromStr;
Expand Down Expand Up @@ -541,3 +542,24 @@ fn asset_code_from_str_to_string_roundtrip_unicode() {
assert_eq!(AssetCode::CreditAlphanum4(AssetCode4(*b"a\xc3\xc3d")).to_string(), r"a\xc3\xc3d");
assert_eq!(AssetCode::from_str(r"a\xc3\xc3d"), Ok(AssetCode::CreditAlphanum4(AssetCode4(*b"a\xc3\xc3d"))));
}

#[test]
#[rustfmt::skip]
fn claimable_balance_id() {
assert_eq!(
ClaimableBalanceId::ClaimableBalanceIdTypeV0(Hash([1u8; 32])).to_string(),
"000000000101010101010101010101010101010101010101010101010101010101010101",
);
// Valid
assert_eq!(ClaimableBalanceId::from_str("000000000101010101010101010101010101010101010101010101010101010101010101"), Ok(ClaimableBalanceId::ClaimableBalanceIdTypeV0(Hash([1u8; 32]))));
// Half byte short.
assert_eq!(ClaimableBalanceId::from_str("00000000010101010101010101010101010101010101010101010101010101010101010"), Err(Error::InvalidHex));
// Full byte short.
assert_eq!(ClaimableBalanceId::from_str("0000000001010101010101010101010101010101010101010101010101010101010101"), Err(Error::Io(std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "failed to fill whole buffer"))));
// Half byte too long.
assert_eq!(ClaimableBalanceId::from_str("0000000001010101010101010101010101010101010101010101010101010101010101011"), Err(Error::InvalidHex));
// Full byte too long.
assert_eq!(ClaimableBalanceId::from_str("00000000010101010101010101010101010101010101010101010101010101010101010101"), Err(Error::Invalid));
// Unrecognized discriminant value.
assert_eq!(ClaimableBalanceId::from_str("000000010101010101010101010101010101010101010101010101010101010101010101"), Err(Error::Invalid));
}

0 comments on commit 31890cf

Please sign in to comment.