Skip to content

Commit 5d99903

Browse files
committed
feat: params.ExtraPayloadGetter[C,R].PointerFromChainConfig(...) *C and Rules => *R equiv
1 parent cc36bed commit 5d99903

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

params/config.libevm.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ func (ExtraPayloadGetter[C, R]) FromChainConfig(c *ChainConfig) C {
152152
return pseudo.MustNewValue[C](c.extraPayload()).Get()
153153
}
154154

155+
// PointerFromChainConfig returns a pointer to the ChainConfig's extra payload.
156+
// This is guaranteed to be non-nil.
157+
func (ExtraPayloadGetter[C, R]) PointerFromChainConfig(c *ChainConfig) *C {
158+
return pseudo.MustPointerTo[C](c.extraPayload()).Value.Get()
159+
}
160+
155161
// hooksFromChainConfig is equivalent to FromChainConfig(), but returns an
156162
// interface instead of the concrete type implementing it; this allows it to be
157163
// used in non-generic code.
@@ -164,6 +170,12 @@ func (ExtraPayloadGetter[C, R]) FromRules(r *Rules) R {
164170
return pseudo.MustNewValue[R](r.extraPayload()).Get()
165171
}
166172

173+
// PointerFromRules returns a pointer to the Rules's extra payload. This is
174+
// guaranteed to be non-nil.
175+
func (ExtraPayloadGetter[C, R]) PointerFromRules(r *Rules) *R {
176+
return pseudo.MustPointerTo[R](r.extraPayload()).Value.Get()
177+
}
178+
167179
// hooksFromRules is the [RulesHooks] equivalent of hooksFromChainConfig().
168180
func (e ExtraPayloadGetter[C, R]) hooksFromRules(r *Rules) RulesHooks {
169181
return e.FromRules(r)

params/config.libevm_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,57 @@ func TestRegisterExtras(t *testing.T) {
121121
}
122122
}
123123

124+
func TestZeroExtrasAndPointers(t *testing.T) {
125+
type (
126+
ccExtra struct {
127+
X int
128+
NOOPHooks
129+
}
130+
rulesExtra struct {
131+
X int
132+
NOOPHooks
133+
}
134+
)
135+
136+
TestOnlyClearRegisteredExtras()
137+
t.Cleanup(TestOnlyClearRegisteredExtras)
138+
getter := RegisterExtras(Extras[ccExtra, rulesExtra]{})
139+
140+
var (
141+
config ChainConfig
142+
rules Rules
143+
)
144+
// These assertion helpers are defined before any modifications so that the
145+
// closure is demonstrably over the original zero values.
146+
assertChainConfigExtra := func(t *testing.T, want ccExtra, msg string) {
147+
t.Helper()
148+
assert.Equalf(t, want, getter.FromChainConfig(&config), "%T: "+msg, &config)
149+
}
150+
assertRulesExtra := func(t *testing.T, want rulesExtra, msg string) {
151+
t.Helper()
152+
assert.Equalf(t, want, getter.FromRules(&rules), "%T: "+msg, &rules)
153+
}
154+
155+
assertChainConfigExtra(t, ccExtra{}, "zero value")
156+
assertRulesExtra(t, rulesExtra{}, "zero value")
157+
158+
const answer = 42
159+
getter.PointerFromChainConfig(&config).X = answer
160+
assertChainConfigExtra(t, ccExtra{X: answer}, "after setting via pointer field")
161+
162+
const pi = 314159
163+
getter.PointerFromRules(&rules).X = pi
164+
assertRulesExtra(t, rulesExtra{X: pi}, "after setting via pointer field")
165+
166+
ccReplace := ccExtra{X: 142857}
167+
*getter.PointerFromChainConfig(&config) = ccReplace
168+
assertChainConfigExtra(t, ccReplace, "after replacement of entire extra via `*pointer = x`")
169+
170+
rulesReplace := rulesExtra{X: 18101986}
171+
*getter.PointerFromRules(&rules) = rulesReplace
172+
assertRulesExtra(t, rulesReplace, "after replacement of entire extra via `*pointer = x`")
173+
}
174+
124175
func TestExtrasPanic(t *testing.T) {
125176
TestOnlyClearRegisteredExtras()
126177
defer TestOnlyClearRegisteredExtras()

0 commit comments

Comments
 (0)