Skip to content

Commit 6a9b643

Browse files
committed
Fix slice handling in go-gen
1 parent c26f382 commit 6a9b643

File tree

3 files changed

+28
-12
lines changed

3 files changed

+28
-12
lines changed

packages/go-gen/src/go.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,16 @@ impl Display for GoField {
5050
self.ty,
5151
self.rust_name
5252
)?;
53-
if let Nullability::OmitEmpty | Nullability::Nullable = self.ty.nullability {
54-
f.write_str(",omitempty")?;
53+
match self.ty.nullability {
54+
Nullability::OmitEmpty => {
55+
f.write_str(",omitempty")?;
56+
}
57+
Nullability::Nullable if !self.ty.is_slice() => {
58+
// if the type is nullable, we need to use a pointer type
59+
// and add `omitempty` to the json tag
60+
f.write_str(",omitempty")?;
61+
}
62+
_ => {}
5563
}
5664
f.write_str("\"`")
5765
}
@@ -100,12 +108,17 @@ impl GoType {
100108
];
101109
BASIC_GO_TYPES.contains(&&*self.name)
102110
}
111+
112+
pub fn is_slice(&self) -> bool {
113+
self.name.starts_with("[]")
114+
}
103115
}
104116

105117
impl Display for GoType {
106118
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107-
if self.nullability == Nullability::Nullable && !self.is_basic_type() {
119+
if self.nullability == Nullability::Nullable && !self.is_basic_type() && !self.is_slice() {
108120
// if the type is nullable and not a basic type, use a pointer
121+
// slices are already pointers, so we don't need to do anything for them
109122
f.write_char('*')?;
110123
}
111124
f.write_str(&self.name)

packages/go-gen/src/main.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ mod tests {
198198

199199
use super::*;
200200

201+
#[track_caller]
201202
fn assert_code_eq(actual: String, expected: &str) {
202203
let actual_no_ws = actual.split_whitespace().collect::<Vec<_>>();
203204
let expected_no_ws = expected.split_whitespace().collect::<Vec<_>>();
@@ -210,6 +211,7 @@ mod tests {
210211
);
211212
}
212213

214+
#[track_caller]
213215
fn assert_code_eq_ignore_docs(actual: String, expected: &str) {
214216
let actual_filtered = actual
215217
.lines()
@@ -251,7 +253,7 @@ mod tests {
251253
Binary []byte `json:"binary"`
252254
Checksum Checksum `json:"checksum"`
253255
HexBinary string `json:"hex_binary"`
254-
NestedBinary Array[*[]byte] `json:"nested_binary"`
256+
NestedBinary Array[[]byte] `json:"nested_binary"`
255257
Uint128 string `json:"uint128"`
256258
}"#,
257259
);
@@ -340,7 +342,7 @@ mod tests {
340342
compare_codes!(cosmwasm_std::SupplyResponse);
341343
compare_codes!(cosmwasm_std::BalanceResponse);
342344
compare_codes!(cosmwasm_std::DenomMetadataResponse);
343-
// compare_codes!(cosmwasm_std::AllDenomMetadataResponse); // uses `[]byte` instead of `*[]byte`
345+
// compare_codes!(cosmwasm_std::AllDenomMetadataResponse); // uses slice instead of `Array` type
344346
// staking
345347
compare_codes!(cosmwasm_std::BondedDenomResponse);
346348
compare_codes!(cosmwasm_std::AllDelegationsResponse);
@@ -355,7 +357,7 @@ mod tests {
355357
// wasm
356358
compare_codes!(cosmwasm_std::ContractInfoResponse);
357359
compare_codes!(cosmwasm_std::CodeInfoResponse);
358-
// compare_codes!(cosmwasm_std::RawRangeResponse); // uses `[]byte` instead of `*[]byte`
360+
compare_codes!(cosmwasm_std::RawRangeResponse);
359361
}
360362

361363
#[test]
@@ -426,8 +428,7 @@ mod tests {
426428
compare_codes!(cosmwasm_std::StakingQuery);
427429
compare_codes!(cosmwasm_std::DistributionQuery);
428430
compare_codes!(cosmwasm_std::IbcQuery);
429-
// TODO: RawRange query uses *[]byte instead of []byte
430-
// compare_codes!(cosmwasm_std::WasmQuery);
431+
compare_codes!(cosmwasm_std::WasmQuery);
431432
}
432433

433434
#[test]
@@ -477,6 +478,8 @@ mod tests {
477478

478479
#[cw_serde]
479480
struct D {
481+
// this should not get an `omitempty` because that prevents us from distinguishing between
482+
// `None` and `Some(vec![])`
480483
d: Option<Vec<String>>,
481484
nested: Vec<Option<Vec<String>>>,
482485
}
@@ -485,8 +488,8 @@ mod tests {
485488
code,
486489
r#"
487490
type D struct {
488-
D *[]string `json:"d,omitempty"`
489-
Nested Array[*[]string] `json:"nested"`
491+
D []string `json:"d"`
492+
Nested Array[[]string] `json:"nested"`
490493
}"#,
491494
);
492495
}

packages/go-gen/src/schema.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ pub fn type_from_instance_type(
212212

213213
// for nullable array item types, we have to use a pointer type, even for basic types,
214214
// so we can pass null as elements
215-
// otherwise they would just be omitted from the array
216-
let maybe_ptr = if item_type.nullability == Nullability::Nullable {
215+
// otherwise they would just be omitted from the array, unless it's a slice itself
216+
let maybe_ptr = if item_type.nullability == Nullability::Nullable && !item_type.is_slice() {
217217
"*"
218218
} else {
219219
""

0 commit comments

Comments
 (0)