Skip to content

Commit d37d8dd

Browse files
committed
feat: options.ApplyTo for default values
1 parent 4bc19e9 commit d37d8dd

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

libevm/options/example_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2025 the libevm authors.
2+
//
3+
// The libevm additions to go-ethereum are free software: you can redistribute
4+
// them and/or modify them under the terms of the GNU Lesser General Public License
5+
// as published by the Free Software Foundation, either version 3 of the License,
6+
// or (at your option) any later version.
7+
//
8+
// The libevm additions are distributed in the hope that they will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11+
// General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Lesser General Public License
14+
// along with the go-ethereum library. If not, see
15+
// <http://www.gnu.org/licenses/>.
16+
17+
package options_test
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/ava-labs/libevm/libevm/options"
23+
)
24+
25+
// config is an arbitrary type to be configured with [options.Option] values.
26+
// Although it can be exported, there is typically no need.
27+
type config struct {
28+
num int
29+
flag bool
30+
}
31+
32+
// An Option configures an arbitrary type. Using a type alias (=) instead of a
33+
// completely new type is recommended as it maintains compatibility with helpers
34+
// such as [options.Func].
35+
type Option = options.Option[config]
36+
37+
func WithNum(n int) Option {
38+
return options.Func[config](func(c *config) {
39+
c.num = n
40+
})
41+
}
42+
43+
func WithFlag(b bool) Option {
44+
return options.Func[config](func(c *config) {
45+
c.flag = b
46+
})
47+
}
48+
49+
func Example() {
50+
num42 := WithNum(42)
51+
flagOn := WithFlag(true)
52+
53+
// Some IDEs and linters might complain about the redundant type parameter
54+
// as it can be inferred, but it makes for more readable code.
55+
fromZero := options.As[config](num42, flagOn)
56+
fmt.Printf("From zero value: %T(%+[1]v)\n", fromZero)
57+
58+
fromDefault := options.ApplyTo(&config{
59+
num: 100,
60+
}, flagOn)
61+
fmt.Printf("Applied to default value: %T(%+[1]v)\n", fromDefault)
62+
63+
// Output:
64+
// From zero value: *options_test.config(&{num:42 flag:true})
65+
// Applied to default value: *options_test.config(&{num:100 flag:true})
66+
}

libevm/options/options.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@ type Option[T any] interface {
2626
// As applies Options to a zero-value T, which it then returns.
2727
func As[T any](opts ...Option[T]) *T {
2828
var t T
29+
return ApplyTo(&t, opts...)
30+
}
31+
32+
// ApplyTo applies Options to the T and returns it for convenience.
33+
func ApplyTo[T any](t *T, opts ...Option[T]) *T {
2934
for _, o := range opts {
30-
o.Configure(&t)
35+
o.Configure(t)
3136
}
32-
return &t
37+
return t
3338
}
3439

3540
// A Func converts a function into an [Option], using itself as the Configure

0 commit comments

Comments
 (0)