Skip to content

Commit

Permalink
Fix render of AssetCode12 to JSON when shorter than 5 chars
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmcculloch committed Apr 5, 2024
1 parent 3a001b1 commit f6fbe2d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 18 deletions.
19 changes: 15 additions & 4 deletions src/curr/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,21 @@ impl core::str::FromStr for AssetCode12 {

impl core::fmt::Display for AssetCode12 {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if let Some(last_idx) = self.0.iter().rposition(|c| *c != 0) {
for b in escape_bytes::Escape::new(&self.0[..=last_idx]) {
write!(f, "{}", b as char)?;
}
// AssetCode12's are always rendered as at least 5 characters, because
// any asset code shorter than 5 characters is an AssetCode4.
// AssetCode12 contains a fixed length 12-byte array, and the constant
// and slices in this function never operate out-of-bounds because of
// that.
const MIN_LENGTH: usize = 5;
let len = MIN_LENGTH
+ self
.0
.iter()
.skip(MIN_LENGTH)
.rposition(|c| *c != 0)
.map_or(0, |last_idx| last_idx + 1);
for b in escape_bytes::Escape::new(&self.0[..len]) {
write!(f, "{}", b as char)?;
}
Ok(())
}
Expand Down
28 changes: 14 additions & 14 deletions tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,11 +450,11 @@ fn asset_code_12_from_str() {
#[test]
#[rustfmt::skip]
fn asset_code_12_to_string() {
assert_eq!(AssetCode12(*b"\0\0\0\0\0\0\0\0\0\0\0\0").to_string(), "");
assert_eq!(AssetCode12(*b"a\0\0\0\0\0\0\0\0\0\0\0").to_string(), "a");
assert_eq!(AssetCode12(*b"ab\0\0\0\0\0\0\0\0\0\0").to_string(), "ab");
assert_eq!(AssetCode12(*b"abc\0\0\0\0\0\0\0\0\0").to_string(), "abc");
assert_eq!(AssetCode12(*b"abcd\0\0\0\0\0\0\0\0").to_string(), "abcd");
assert_eq!(AssetCode12(*b"\0\0\0\0\0\0\0\0\0\0\0\0").to_string(), r"\0\0\0\0\0");
assert_eq!(AssetCode12(*b"a\0\0\0\0\0\0\0\0\0\0\0").to_string(), r"a\0\0\0\0");
assert_eq!(AssetCode12(*b"ab\0\0\0\0\0\0\0\0\0\0").to_string(), r"ab\0\0\0");
assert_eq!(AssetCode12(*b"abc\0\0\0\0\0\0\0\0\0").to_string(), r"abc\0\0");
assert_eq!(AssetCode12(*b"abcd\0\0\0\0\0\0\0\0").to_string(), r"abcd\0");
assert_eq!(AssetCode12(*b"abcde\0\0\0\0\0\0\0").to_string(), "abcde");
assert_eq!(AssetCode12(*b"abcdef\0\0\0\0\0\0").to_string(), "abcdef");
assert_eq!(AssetCode12(*b"abcdefg\0\0\0\0\0").to_string(), "abcdefg");
Expand All @@ -465,10 +465,10 @@ fn asset_code_12_to_string() {
assert_eq!(AssetCode12(*b"abcdefghijkl").to_string(), "abcdefghijkl");

// Preserve as much of the code as possible, even if it contains nul bytes.
assert_eq!(AssetCode12(*b"a\0cd\0\0\0\0\0\0\0\0").to_string(), r"a\0cd");
assert_eq!(AssetCode12(*b"a\0cd\0\0\0\0\0\0\0\0").to_string(), r"a\0cd\0");

// Replace bytes that are not valid utf8 with the replacement character � and preserve length.
assert_eq!(AssetCode12(*b"a\xc3\x28d\0\0\0\0\0\0\0\0").to_string(), r"a\xc3(d");
assert_eq!(AssetCode12(*b"a\xc3\x28d\0\0\0\0\0\0\0\0").to_string(), r"a\xc3(d\0");
assert_eq!(AssetCode12(*b"a\xc3\xc3\x28d\0\0\0\0\0\0\0").to_string(), r"a\xc3\xc3(d");
}

Expand Down Expand Up @@ -502,11 +502,11 @@ fn asset_code_to_string() {
assert_eq!(AssetCode::CreditAlphanum4(AssetCode4(*b"abc\0")).to_string(), "abc");
assert_eq!(AssetCode::CreditAlphanum4(AssetCode4(*b"abcd")).to_string(), "abcd");

assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"\0\0\0\0\0\0\0\0\0\0\0\0")).to_string(), "");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"a\0\0\0\0\0\0\0\0\0\0\0")).to_string(), "a");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"ab\0\0\0\0\0\0\0\0\0\0")).to_string(), "ab");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"abc\0\0\0\0\0\0\0\0\0")).to_string(), "abc");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"abcd\0\0\0\0\0\0\0\0")).to_string(), "abcd");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"\0\0\0\0\0\0\0\0\0\0\0\0")).to_string(), r"\0\0\0\0\0");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"a\0\0\0\0\0\0\0\0\0\0\0")).to_string(), r"a\0\0\0\0");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"ab\0\0\0\0\0\0\0\0\0\0")).to_string(), r"ab\0\0\0");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"abc\0\0\0\0\0\0\0\0\0")).to_string(), r"abc\0\0");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"abcd\0\0\0\0\0\0\0\0")).to_string(), r"abcd\0");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"abcde\0\0\0\0\0\0\0")).to_string(), "abcde");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"abcdef\0\0\0\0\0\0")).to_string(), "abcdef");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"abcdefg\0\0\0\0\0")).to_string(), "abcdefg");
Expand All @@ -518,11 +518,11 @@ fn asset_code_to_string() {

// Preserve as much of the code as possible, even if it contains nul bytes.
assert_eq!(AssetCode::CreditAlphanum4(AssetCode4(*b"a\0cd")).to_string(), r"a\0cd");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"a\0cd\0\0\0\0\0\0\0\0")).to_string(), r"a\0cd");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"a\0cd\0\0\0\0\0\0\0\0")).to_string(), r"a\0cd\0");

// Replace bytes that are not valid utf8 with the replacement character � and preserve length.
assert_eq!(AssetCode::CreditAlphanum4(AssetCode4(*b"a\xc3\x28d")).to_string(), r"a\xc3(d");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"a\xc3\x28d\0\0\0\0\0\0\0\0")).to_string(), r"a\xc3(d");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"a\xc3\x28d\0\0\0\0\0\0\0\0")).to_string(), r"a\xc3(d\0");
assert_eq!(AssetCode::CreditAlphanum12(AssetCode12(*b"a\xc3\xc3\x28d\0\0\0\0\0\0\0")).to_string(), r"a\xc3\xc3(d");
}

Expand Down

0 comments on commit f6fbe2d

Please sign in to comment.