Skip to content

Commit 95230f6

Browse files
tamirmsclaude
andcommitted
Fix Box wrapping in hand-written conversions and regenerate
The generator wraps recursive types (ScVec, ScMap, ScMapEntry fields) in Box to break cycles. Update scval_conversions.rs, scval_validations.rs, and scmap.rs to use Box::new() when constructing these types and to dereference when extracting. Regenerate with generate_to_dir (per-file output matching main). Add #[allow(dead_code)] on unused per-file output types. Fix Makefile xdr-definitions-json target path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 160756c commit 95230f6

File tree

9 files changed

+109
-106
lines changed

9 files changed

+109
-106
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ xdr-json: src/generated.rs
5252
mkdir -p xdr-json
5353
cargo run --features cli -- types schema-files --out-dir xdr-json
5454

55-
xdr-definitions-json: $(sort $(wildcard xdr/curr/*.x))
55+
xdr-definitions-json: $(sort $(wildcard xdr/*.x))
5656
mkdir -p xdr-definitions-json
5757
cargo run --manifest-path xdr-generator-rust/generator/Cargo.toml -- \
58-
$(addprefix --input ,$(sort $(wildcard xdr/curr/*.x))) \
59-
--json-ast xdr-definitions-json/curr.json
58+
$(addprefix --input ,$(sort $(wildcard xdr/*.x))) \
59+
--json-ast xdr-definitions-json/xdr.json
6060

6161
clean:
6262
rm -f src/generated.rs

src/generated/sc_contract_instance.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use super::*;
2323
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2424
pub struct ScContractInstance {
2525
pub executable: ContractExecutable,
26-
pub storage: Option<ScMap>,
26+
pub storage: Option<Box<ScMap>>,
2727
}
2828

2929
impl ReadXdr for ScContractInstance {
@@ -32,7 +32,7 @@ impl ReadXdr for ScContractInstance {
3232
r.with_limited_depth(|r| {
3333
Ok(Self {
3434
executable: ContractExecutable::read_xdr(r)?,
35-
storage: Option::<ScMap>::read_xdr(r)?,
35+
storage: Option::<Box<ScMap>>::read_xdr(r)?,
3636
})
3737
})
3838
}

src/generated/sc_map_entry.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ use super::*;
2323
)]
2424
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2525
pub struct ScMapEntry {
26-
pub key: ScVal,
27-
pub val: ScVal,
26+
pub key: Box<ScVal>,
27+
pub val: Box<ScVal>,
2828
}
2929

3030
impl ReadXdr for ScMapEntry {
3131
#[cfg(feature = "std")]
3232
fn read_xdr<R: Read>(r: &mut Limited<R>) -> Result<Self, Error> {
3333
r.with_limited_depth(|r| {
3434
Ok(Self {
35-
key: ScVal::read_xdr(r)?,
36-
val: ScVal::read_xdr(r)?,
35+
key: Box::<ScVal>::read_xdr(r)?,
36+
val: Box::<ScVal>::read_xdr(r)?,
3737
})
3838
})
3939
}

src/generated/sc_val.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ pub enum ScVal {
107107
Bytes(ScBytes),
108108
String(ScString),
109109
Symbol(ScSymbol),
110-
Vec(Option<ScVec>),
111-
Map(Option<ScMap>),
110+
Vec(Option<Box<ScVec>>),
111+
Map(Option<Box<ScMap>>),
112112
Address(ScAddress),
113-
ContractInstance(ScContractInstance),
113+
ContractInstance(Box<ScContractInstance>),
114114
LedgerKeyContractInstance,
115115
LedgerKeyNonce(ScNonceKey),
116116
}
@@ -298,11 +298,11 @@ impl ReadXdr for ScVal {
298298
ScValType::Bytes => Self::Bytes(ScBytes::read_xdr(r)?),
299299
ScValType::String => Self::String(ScString::read_xdr(r)?),
300300
ScValType::Symbol => Self::Symbol(ScSymbol::read_xdr(r)?),
301-
ScValType::Vec => Self::Vec(Option::<ScVec>::read_xdr(r)?),
302-
ScValType::Map => Self::Map(Option::<ScMap>::read_xdr(r)?),
301+
ScValType::Vec => Self::Vec(Option::<Box<ScVec>>::read_xdr(r)?),
302+
ScValType::Map => Self::Map(Option::<Box<ScMap>>::read_xdr(r)?),
303303
ScValType::Address => Self::Address(ScAddress::read_xdr(r)?),
304304
ScValType::ContractInstance => {
305-
Self::ContractInstance(ScContractInstance::read_xdr(r)?)
305+
Self::ContractInstance(Box::<ScContractInstance>::read_xdr(r)?)
306306
}
307307
ScValType::LedgerKeyContractInstance => Self::LedgerKeyContractInstance,
308308
ScValType::LedgerKeyNonce => Self::LedgerKeyNonce(ScNonceKey::read_xdr(r)?),

src/scmap.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,17 @@ mod test {
5252
m.insert(5, 6);
5353
m.insert(3, 4);
5454
let scm = ScMap::sorted_from(m)?;
55-
assert_eq!(scm.0.first().unwrap().key, 1u32.into());
56-
assert_eq!(scm.0.last().unwrap().key, 5u32.into());
55+
assert_eq!(*scm.0.first().unwrap().key, 1u32.into());
56+
assert_eq!(*scm.0.last().unwrap().key, 5u32.into());
5757
Ok(())
5858
}
5959

6060
#[test]
6161
fn scmap_from_pairs() -> Result<(), ()> {
6262
let pairs: Vec<(u32, u32)> = vec![(3, 4), (5, 6), (1, 2)];
6363
let scm = ScMap::sorted_from(pairs)?;
64-
assert_eq!(scm.0.first().unwrap().key, 1u32.into());
65-
assert_eq!(scm.0.last().unwrap().key, 5u32.into());
64+
assert_eq!(*scm.0.first().unwrap().key, 1u32.into());
65+
assert_eq!(*scm.0.last().unwrap().key, 5u32.into());
6666
Ok(())
6767
}
6868

src/scval_conversions.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use super::{
55
#[cfg(all(not(feature = "std"), feature = "alloc"))]
66
extern crate alloc;
77
#[cfg(all(not(feature = "std"), feature = "alloc"))]
8-
use alloc::{string::String, vec, vec::Vec};
8+
use alloc::{boxed::Box, string::String, vec, vec::Vec};
9+
#[cfg(all(feature = "std", feature = "alloc"))]
10+
use std::boxed::Box;
911

1012
// TODO: Use the Error type for conversions in this file.
1113

@@ -404,54 +406,55 @@ impl TryFrom<&ScVal> for Vec<u8> {
404406
}
405407
}
406408

409+
#[cfg(feature = "alloc")]
407410
impl From<ScVec> for ScVal {
408411
fn from(v: ScVec) -> Self {
409-
ScVal::Vec(Some(v))
412+
ScVal::Vec(Some(Box::new(v)))
410413
}
411414
}
412415

413416
#[cfg(feature = "alloc")]
414417
impl<T: TryInto<ScVal>> TryFrom<Vec<T>> for ScVal {
415418
type Error = ();
416419
fn try_from(v: Vec<T>) -> Result<Self, ()> {
417-
Ok(ScVal::Vec(Some(
420+
Ok(ScVal::Vec(Some(Box::new(
418421
v.into_iter()
419422
.map(|t| <_ as TryInto<ScVal>>::try_into(t))
420423
.collect::<Result<Vec<_>, _>>() // TODO: Impl conversion from Iterator to VecM in generated code.
421424
.map_err(|_| ())?
422425
.try_into()
423426
.map_err(|_| ())?,
424-
)))
427+
))))
425428
}
426429
}
427430

428431
#[cfg(feature = "alloc")]
429432
impl<T: TryInto<ScVal> + Clone> TryFrom<&Vec<T>> for ScVal {
430433
type Error = ();
431434
fn try_from(v: &Vec<T>) -> Result<Self, ()> {
432-
Ok(ScVal::Vec(Some(
435+
Ok(ScVal::Vec(Some(Box::new(
433436
v.iter()
434437
.map(|t| <_ as TryInto<ScVal>>::try_into(t.clone()))
435438
.collect::<Result<Vec<_>, _>>() // TODO: Impl conversion from Iterator to VecM in generated code.
436439
.map_err(|_| ())?
437440
.try_into()
438441
.map_err(|_| ())?,
439-
)))
442+
))))
440443
}
441444
}
442445

443446
#[cfg(feature = "alloc")]
444447
impl<T: TryInto<ScVal> + Clone> TryFrom<&[T]> for ScVal {
445448
type Error = ();
446449
fn try_from(v: &[T]) -> Result<Self, ()> {
447-
Ok(ScVal::Vec(Some(
450+
Ok(ScVal::Vec(Some(Box::new(
448451
v.iter()
449452
.map(|t| <_ as TryInto<ScVal>>::try_into(t.clone()))
450453
.collect::<Result<Vec<_>, _>>() // TODO: Impl conversion from Iterator to VecM in generated code.
451454
.map_err(|_| ())?
452455
.try_into()
453456
.map_err(|_| ())?,
454-
)))
457+
))))
455458
}
456459
}
457460

@@ -469,23 +472,26 @@ impl<T: TryFrom<ScVal> + Clone> TryFrom<ScVal> for Vec<T> {
469472
}
470473
}
471474

475+
#[cfg(feature = "alloc")]
472476
impl From<ScMap> for ScVal {
473477
fn from(v: ScMap) -> Self {
474-
ScVal::Map(Some(v))
478+
ScVal::Map(Some(Box::new(v)))
475479
}
476480
}
477481

482+
#[cfg(feature = "alloc")]
478483
impl TryFrom<ScVal> for ScMap {
479484
type Error = ();
480485
fn try_from(v: ScVal) -> Result<Self, Self::Error> {
481486
if let ScVal::Map(Some(m)) = v {
482-
Ok(m)
487+
Ok(*m)
483488
} else {
484489
Err(())
485490
}
486491
}
487492
}
488493

494+
#[cfg(feature = "alloc")]
489495
impl<K, V> TryFrom<(K, V)> for ScMapEntry
490496
where
491497
K: TryInto<ScVal>,
@@ -495,8 +501,8 @@ where
495501

496502
fn try_from(v: (K, V)) -> Result<Self, Self::Error> {
497503
Ok(ScMapEntry {
498-
key: v.0.try_into().map_err(|_| ())?,
499-
val: v.1.try_into().map_err(|_| ())?,
504+
key: Box::new(v.0.try_into().map_err(|_| ())?),
505+
val: Box::new(v.1.try_into().map_err(|_| ())?),
500506
})
501507
}
502508
}
@@ -561,7 +567,7 @@ macro_rules! impl_for_tuple {
561567
{
562568
type Error = ();
563569
fn try_from(v: ($($typ,)*)) -> Result<Self, ()> {
564-
Ok(ScVal::Vec(Some(<_ as TryInto<ScVec>>::try_into(v)?)))
570+
Ok(ScVal::Vec(Some(Box::new(<_ as TryInto<ScVec>>::try_into(v)?))))
565571
}
566572
}
567573

@@ -572,10 +578,11 @@ macro_rules! impl_for_tuple {
572578
{
573579
type Error = ();
574580
fn try_from(v: &($($typ,)*)) -> Result<Self, ()> {
575-
Ok(ScVal::Vec(Some(<_ as TryInto<ScVec>>::try_into(v)?)))
581+
Ok(ScVal::Vec(Some(Box::new(<_ as TryInto<ScVec>>::try_into(v)?))))
576582
}
577583
}
578584

585+
#[cfg(feature = "alloc")]
579586
impl<$($typ),*> TryFrom<ScVec> for ($($typ,)*)
580587
where
581588
// TODO: Consider removing the Clone constraint by changing the
@@ -598,6 +605,7 @@ macro_rules! impl_for_tuple {
598605
}
599606
}
600607

608+
#[cfg(feature = "alloc")]
601609
impl<$($typ),*> TryFrom<ScVal> for ($($typ,)*)
602610
where
603611
$($typ: TryFrom<ScVal> + Clone),*
@@ -606,7 +614,7 @@ macro_rules! impl_for_tuple {
606614

607615
fn try_from(obj: ScVal) -> Result<Self, Self::Error> {
608616
if let ScVal::Vec(Some(vec)) = obj {
609-
<_ as TryFrom<ScVec>>::try_from(vec)
617+
<_ as TryFrom<ScVec>>::try_from(*vec)
610618
} else {
611619
Err(())
612620
}
@@ -810,6 +818,7 @@ mod test {
810818
assert_eq!(val, ScVal::Void);
811819
}
812820

821+
#[cfg(feature = "alloc")]
813822
#[test]
814823
fn scval_from() {
815824
let _ = ScVal::from(ScVec::default());

src/scval_validations.rs

Lines changed: 26 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -101,78 +101,47 @@ mod test {
101101
fn map() {
102102
use super::super::{ScMap, ScMapEntry};
103103
extern crate alloc;
104-
use alloc::vec;
104+
use alloc::{boxed::Box, vec, vec::Vec};
105+
106+
let entry = |key: ScVal, val: ScVal| ScMapEntry {
107+
key: Box::new(key),
108+
val: Box::new(val),
109+
};
110+
let map = |entries: Vec<ScMapEntry>| -> ScVal {
111+
ScVal::Map(Some(Box::new(ScMap(entries.try_into().unwrap()))))
112+
};
113+
105114
// Maps should be sorted by key and have no duplicates. The sort order
106115
// is just the "normal" sort order on ScVal emitted by derive(PartialOrd).
107116
assert_eq!(
108-
ScVal::Map(Some(ScMap(
109-
vec![
110-
ScMapEntry {
111-
key: ScVal::I64(0),
112-
val: ScVal::U32(1),
113-
},
114-
ScMapEntry {
115-
key: ScVal::I64(1),
116-
val: ScVal::I64(1),
117-
}
118-
]
119-
.try_into()
120-
.unwrap()
121-
)))
117+
map(vec![
118+
entry(ScVal::I64(0), ScVal::U32(1)),
119+
entry(ScVal::I64(1), ScVal::I64(1)),
120+
])
122121
.validate(),
123122
Ok(())
124123
);
125124
assert_eq!(
126-
ScVal::Map(Some(ScMap(
127-
vec![
128-
ScMapEntry {
129-
key: ScVal::I64(0),
130-
val: ScVal::I64(1),
131-
},
132-
ScMapEntry {
133-
key: ScVal::I64(1),
134-
val: ScVal::I64(1),
135-
}
136-
]
137-
.try_into()
138-
.unwrap()
139-
)))
125+
map(vec![
126+
entry(ScVal::I64(0), ScVal::I64(1)),
127+
entry(ScVal::I64(1), ScVal::I64(1)),
128+
])
140129
.validate(),
141130
Ok(())
142131
);
143132
assert_eq!(
144-
ScVal::Map(Some(ScMap(
145-
vec![
146-
ScMapEntry {
147-
key: ScVal::I64(2),
148-
val: ScVal::I64(1),
149-
},
150-
ScMapEntry {
151-
key: ScVal::I64(1),
152-
val: ScVal::I64(1),
153-
}
154-
]
155-
.try_into()
156-
.unwrap()
157-
)))
133+
map(vec![
134+
entry(ScVal::I64(2), ScVal::I64(1)),
135+
entry(ScVal::I64(1), ScVal::I64(1)),
136+
])
158137
.validate(),
159138
Err(Error::Invalid)
160139
);
161140
assert_eq!(
162-
ScVal::Map(Some(ScMap(
163-
vec![
164-
ScMapEntry {
165-
key: ScVal::I64(2),
166-
val: ScVal::I64(1),
167-
},
168-
ScMapEntry {
169-
key: ScVal::U32(1),
170-
val: ScVal::I64(1),
171-
},
172-
]
173-
.try_into()
174-
.unwrap()
175-
)))
141+
map(vec![
142+
entry(ScVal::I64(2), ScVal::I64(1)),
143+
entry(ScVal::U32(1), ScVal::I64(1)),
144+
])
176145
.validate(),
177146
Err(Error::Invalid)
178147
);

0 commit comments

Comments
 (0)