Skip to content

Commit

Permalink
Merge branch 'main' into feature/toolkit-receipt-support
Browse files Browse the repository at this point in the history
  • Loading branch information
0xOmarA committed Sep 6, 2024
2 parents 12a9ce3 + 6fcf811 commit a491f7f
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 1 deletion.
32 changes: 31 additions & 1 deletion crates/sbor-json/src/scrypto/programmatic/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ pub enum ProgrammaticScryptoValue {
},
Enum {
#[serde(rename = "variant_id")]
#[serde_as(as = "serde_with::DisplayFromStr")]
// TODO: Revert back once the gateway is past the transition phase.
// #[serde_as(as = "serde_with::DisplayFromStr")]
#[serde(serialize_with = "serialize_enum_discriminator")]
#[serde(deserialize_with = "deserialize_enum_discriminator")]
discriminator: u8,
fields: Vec<ProgrammaticScryptoValue>,
},
Expand Down Expand Up @@ -418,3 +421,30 @@ impl ProgrammaticScryptoValue {
}
}
}

fn serialize_enum_discriminator<S>(
value: &u8,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(&value.to_string())
}

fn deserialize_enum_discriminator<'de, D>(
deserializer: D,
) -> Result<u8, D::Error>
where
D: serde::de::Deserializer<'de>,
{
match serde_json::Value::deserialize(deserializer)? {
serde_json::Value::Number(number) => number
.as_u64()
.and_then(|value| u8::try_from(value).ok())
.ok_or(serde::de::Error::custom("Not a valid number")),
serde_json::Value::String(string) => u8::from_str(&string)
.map_err(|_| serde::de::Error::custom("Not a valid number")),
_ => Err(serde::de::Error::custom("Neither a number nor a string")),
}
}
66 changes: 66 additions & 0 deletions crates/sbor-json/tests/programmatic_scrypto_sbor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,72 @@ pub fn value_with_two_address_of_the_differing_networks_has_a_network_mismatch()
assert!(contains_network_mismatch)
}

#[test]
pub fn enum_with_string_variant_id_can_be_deserialized() {
// Arrange
let value = r#"
{
"kind": "Enum",
"variant_id": "10",
"fields": []
}
"#;

// Act
let value = serde_json::from_str::<ProgrammaticScryptoValue>(&value);

// Assert
assert!(matches!(
value,
Ok(ProgrammaticScryptoValue::Enum {
discriminator: 10,
fields,
}) if fields.is_empty()
))
}

#[test]
pub fn enum_with_numeric_variant_id_can_be_deserialized() {
// Arrange
let value = r#"
{
"kind": "Enum",
"variant_id": 10,
"fields": []
}
"#;

// Act
let value = serde_json::from_str::<ProgrammaticScryptoValue>(&value);

// Assert
assert!(matches!(
value,
Ok(ProgrammaticScryptoValue::Enum {
discriminator: 10,
fields,
}) if fields.is_empty()
))
}

#[test]
pub fn enum_is_serialized_with_string_variant_id() {
// Arrange
let value = ProgrammaticScryptoValue::Enum {
discriminator: 10,
fields: vec![],
};

// Act
let value = serde_json::to_value(&value);

// Assert
assert_eq!(
value.unwrap().get("variant_id").unwrap().as_str().unwrap(),
"10"
)
}

/// Tests that the programmatic JSON representation from the
/// radixdlt/radixdlt-scrypto repo and the one in this repo match.
pub fn programmatic_json_representations_match<T>(object: &T)
Expand Down

0 comments on commit a491f7f

Please sign in to comment.