Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/generated/contract_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ use super::*;
pub struct ContractEvent {
pub ext: ExtensionPoint,
pub contract_id: Option<ContractId>,
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "type", alias = "type_")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "type"))]
pub type_: ContractEventType,
pub body: ContractEventBody,
}
Expand Down
5 changes: 5 additions & 0 deletions src/generated/dont_have.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ use super::*;
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct DontHave {
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "type", alias = "type_")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "type"))]
pub type_: MessageType,
pub req_hash: Uint256,
}
Expand Down
5 changes: 5 additions & 0 deletions src/generated/sc_spec_event_param_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ use super::*;
pub struct ScSpecEventParamV0 {
pub doc: StringM<1024>,
pub name: StringM<30>,
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "type", alias = "type_")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "type"))]
pub type_: ScSpecTypeDef,
pub location: ScSpecEventParamLocationV0,
}
Expand Down
5 changes: 5 additions & 0 deletions src/generated/sc_spec_function_input_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ use super::*;
pub struct ScSpecFunctionInputV0 {
pub doc: StringM<1024>,
pub name: StringM<30>,
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "type", alias = "type_")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "type"))]
pub type_: ScSpecTypeDef,
}

Expand Down
5 changes: 5 additions & 0 deletions src/generated/sc_spec_udt_struct_field_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ use super::*;
pub struct ScSpecUdtStructFieldV0 {
pub doc: StringM<1024>,
pub name: StringM<30>,
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "type", alias = "type_")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "type"))]
pub type_: ScSpecTypeDef,
}

Expand Down
5 changes: 5 additions & 0 deletions src/generated/sc_spec_udt_union_case_tuple_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ use super::*;
pub struct ScSpecUdtUnionCaseTupleV0 {
pub doc: StringM<1024>,
pub name: StringM<60>,
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "type", alias = "type_")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "type"))]
pub type_: VecM<ScSpecTypeDef>,
}

Expand Down
5 changes: 5 additions & 0 deletions src/generated/serialized_binary_fuse_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ use super::*;
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct SerializedBinaryFuseFilter {
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "type", alias = "type_")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "type"))]
pub type_: BinaryFuseFilterType,
pub input_hash_seed: ShortHashSeed,
pub filter_seed: ShortHashSeed,
Expand Down
26 changes: 25 additions & 1 deletion tests/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use stellar_xdr::{BytesM, Hash, StringM, VecM};

use stellar_xdr::{AccountId, Int128Parts};
use stellar_xdr::{AccountId, ContractEvent, ContractEventType, Int128Parts};

use std::str::FromStr;

Expand Down Expand Up @@ -78,3 +78,27 @@ fn test_structs_that_ser_to_string_and_dual_der() -> Result<(), Box<dyn std::err
);
Ok(())
}

#[test]
fn test_serde_type_field_uses_sep51_json_key() -> Result<(), Box<dyn std::error::Error>> {
let event = ContractEvent {
type_: ContractEventType::Contract,
..Default::default()
};

// The SEP-51 JSON uses the key `type`, not the previously escaped `type_`.
let json = r#"{"ext":"v0","contract_id":null,"type":"contract","body":{"v0":{"topics":[],"data":{"bool":false}}}}"#;
// The legacy JSON that older versions of this crate emitted, using `type_`.
let legacy_json = r#"{"ext":"v0","contract_id":null,"type_":"contract","body":{"v0":{"topics":[],"data":{"bool":false}}}}"#;

// Serializes with the SEP-51 key `type`.
assert_eq!(serde_json::to_string(&event)?, json);

// Deserializes from the SEP-51 key `type`.
assert_eq!(serde_json::from_str::<ContractEvent>(json)?, event);

// The legacy escaped key `type_` is still accepted via a serde alias.
assert_eq!(serde_json::from_str::<ContractEvent>(legacy_json)?, event);

Ok(())
}
6 changes: 5 additions & 1 deletion xdr-generator-rust/generator/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use xdr_parser::ast::{
use xdr_parser::lexer::IntBase;
use xdr_parser::types::{is_builtin_type, is_fixed_array, is_fixed_opaque, is_var_array, TypeInfo};

use crate::naming::{case_value, field_name, mod_name, source_comment, type_name};
use crate::naming::{
case_value, field_json_rename, field_name, mod_name, source_comment, type_name,
};
use crate::options::RustOptions;
use crate::output::{
ConstOutput, DefinitionOutput, DefinitionTemplate, EnumOutput, EnumStructMemberOutput,
Expand Down Expand Up @@ -424,13 +426,15 @@ impl RustGenerator {
custom_str: bool,
) -> StructMemberOutput {
let name = field_name(&m.name);
let serde_rename = field_json_rename(&m.name);
let resolved = resolve_type(&m.type_, Some(parent), &self.type_info, custom_str);

StructMemberOutput {
name,
type_ref: resolved.type_ref,
turbofish_type: resolved.turbofish_type,
serde_as_type: resolved.serde_as_type,
serde_rename,
}
}

Expand Down
12 changes: 12 additions & 0 deletions xdr-generator-rust/generator/src/naming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ pub(crate) fn field_name(name: &str) -> String {
escape_field_name(&snake)
}

/// If the Rust field name for an XDR field was keyword-escaped away from its
/// plain snake_case name (e.g. `type` -> `type_`), return the correct JSON key
/// (the unescaped snake_case name). Returns `None` when no escaping occurred.
pub(crate) fn field_json_rename(name: &str) -> Option<String> {
let snake = name.to_snake_case();
if escape_field_name(&snake) == snake {
None
} else {
Some(snake)
}
}

fn escape_type_name(name: &str) -> String {
match name {
"type" => "type_".to_string(),
Expand Down
3 changes: 3 additions & 0 deletions xdr-generator-rust/generator/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ pub struct StructMemberOutput {
pub type_ref: String,
pub turbofish_type: String,
pub serde_as_type: Option<String>,
/// The correct SEP-51 JSON key when the Rust field name was keyword-escaped
/// (e.g. `type_` -> JSON `type`). `None` when the name was not escaped.
pub serde_rename: Option<String>,
}

pub struct EnumOutput {
Expand Down
12 changes: 11 additions & 1 deletion xdr-generator-rust/generator/src/tests/naming.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::naming::{field_name, type_name};
use crate::naming::{field_json_rename, field_name, type_name};

#[test]
fn test_type_name_snake_case() {
Expand Down Expand Up @@ -56,6 +56,16 @@ fn test_field_name_escape_type() {
assert_eq!(field_name("type"), "type_");
}

#[test]
fn test_field_json_rename_type() {
assert_eq!(field_json_rename("type"), Some("type".to_string()));
}

#[test]
fn test_field_json_rename_non_keyword() {
assert_eq!(field_json_rename("public_key"), None);
}

#[test]
fn test_field_name_upper_camel_case() {
assert_eq!(field_name("PublicKey"), "public_key");
Expand Down
7 changes: 7 additions & 0 deletions xdr-generator-rust/generator/templates/struct.rs.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ pub struct {{ s.name }} {
all(feature = "serde", feature = "alloc"),
serde_as(as = "{{ serde_as }}")
)]
{%- endif %}
{%- if let Some(rename) = m.serde_rename %}
#[cfg_attr(
all(feature = "serde", feature = "alloc"),
serde(rename = "{{ rename }}", alias = "{{ m.name }}")
)]
#[cfg_attr(feature = "schemars", schemars(rename = "{{ rename }}"))]
{%- endif %}
pub {{ m.name }}: {{ m.type_ref }},
{%- endfor %}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/AuthenticatedMessage.json
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@
"type": "object",
"required": [
"req_hash",
"type_"
"type"
],
"properties": {
"req_hash": {
Expand All @@ -699,7 +699,7 @@
"contentEncoding": "hex",
"contentMediaType": "application/binary"
},
"type_": {
"type": {
"$ref": "#/definitions/MessageType"
}
}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/AuthenticatedMessageV0.json
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@
"type": "object",
"required": [
"req_hash",
"type_"
"type"
],
"properties": {
"req_hash": {
Expand All @@ -681,7 +681,7 @@
"contentEncoding": "hex",
"contentMediaType": "application/binary"
},
"type_": {
"type": {
"$ref": "#/definitions/MessageType"
}
}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/ContractEvent.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"required": [
"body",
"ext",
"type_"
"type"
],
"properties": {
"$schema": {
Expand All @@ -28,7 +28,7 @@
"ext": {
"$ref": "#/definitions/ExtensionPoint"
},
"type_": {
"type": {
"$ref": "#/definitions/ContractEventType"
}
},
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/DiagnosticEvent.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"required": [
"body",
"ext",
"type_"
"type"
],
"properties": {
"body": {
Expand All @@ -45,7 +45,7 @@
"ext": {
"$ref": "#/definitions/ExtensionPoint"
},
"type_": {
"type": {
"$ref": "#/definitions/ContractEventType"
}
}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/DontHave.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "object",
"required": [
"req_hash",
"type_"
"type"
],
"properties": {
"$schema": {
Expand All @@ -18,7 +18,7 @@
"contentEncoding": "hex",
"contentMediaType": "application/binary"
},
"type_": {
"type": {
"$ref": "#/definitions/MessageType"
}
},
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/InvokeHostFunctionSuccessPreImage.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"required": [
"body",
"ext",
"type_"
"type"
],
"properties": {
"body": {
Expand All @@ -49,7 +49,7 @@
"ext": {
"$ref": "#/definitions/ExtensionPoint"
},
"type_": {
"type": {
"$ref": "#/definitions/ContractEventType"
}
}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/LedgerCloseMeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -1659,7 +1659,7 @@
"required": [
"body",
"ext",
"type_"
"type"
],
"properties": {
"body": {
Expand All @@ -1678,7 +1678,7 @@
"ext": {
"$ref": "#/definitions/ExtensionPoint"
},
"type_": {
"type": {
"$ref": "#/definitions/ContractEventType"
}
}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/LedgerCloseMetaBatch.json
Original file line number Diff line number Diff line change
Expand Up @@ -1647,7 +1647,7 @@
"required": [
"body",
"ext",
"type_"
"type"
],
"properties": {
"body": {
Expand All @@ -1666,7 +1666,7 @@
"ext": {
"$ref": "#/definitions/ExtensionPoint"
},
"type_": {
"type": {
"$ref": "#/definitions/ContractEventType"
}
}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/LedgerCloseMetaV0.json
Original file line number Diff line number Diff line change
Expand Up @@ -1659,7 +1659,7 @@
"required": [
"body",
"ext",
"type_"
"type"
],
"properties": {
"body": {
Expand All @@ -1678,7 +1678,7 @@
"ext": {
"$ref": "#/definitions/ExtensionPoint"
},
"type_": {
"type": {
"$ref": "#/definitions/ContractEventType"
}
}
Expand Down
4 changes: 2 additions & 2 deletions xdr-json/LedgerCloseMetaV1.json
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@
"required": [
"body",
"ext",
"type_"
"type"
],
"properties": {
"body": {
Expand All @@ -1702,7 +1702,7 @@
"ext": {
"$ref": "#/definitions/ExtensionPoint"
},
"type_": {
"type": {
"$ref": "#/definitions/ContractEventType"
}
}
Expand Down
Loading
Loading