Skip to content

Commit 4af9c36

Browse files
committed
refactor: split setup logic from service.go into setup.go
1 parent 0bc3bfb commit 4af9c36

2 files changed

Lines changed: 48 additions & 44 deletions

File tree

service.go

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
package payrex
22

3-
import (
4-
"fmt"
5-
"reflect"
6-
"strings"
7-
)
8-
93
// serviceProvider is the interface that all Service types implement.
104
type serviceProvider interface {
115
// setupClient sets up the service by supplying it with the [Client].
126
setupClient(*Client)
13-
// setup sets up the service's other data.
7+
// setup sets up the service's service-specific data.
148
setup()
159
}
1610

@@ -24,40 +18,5 @@ func (s *service[T]) setupClient(client *Client) {
2418
s.client = client
2519
}
2620

27-
// setupServices sets up the Service fields.
28-
func (c *Client) setupServices() {
29-
// I use reflection here mainly just for convenience: whenever new services
30-
// are added I can just add them as a field to Client and I don't have to do anything else.
31-
v := reflect.ValueOf(c).Elem()
32-
for _, fieldName := range serviceFieldNames {
33-
service := v.FieldByName(fieldName).Addr().Interface().(serviceProvider)
34-
35-
service.setupClient(c)
36-
service.setup()
37-
}
38-
}
39-
40-
var serviceFieldNames []string = []string{}
41-
42-
// init checks that all Service fields in the Client struct implement serviceProvider
43-
// and saves the service field names for later use.
44-
func init() {
45-
v := reflect.ValueOf(&Client{}).Elem()
46-
47-
for _, field := range reflect.VisibleFields(v.Type()) {
48-
if !field.IsExported() || !strings.HasPrefix(field.Type.Name(), "Service") {
49-
continue
50-
}
51-
52-
serviceField := v.FieldByName(field.Name).Addr().Interface()
53-
54-
if _, ok := serviceField.(serviceProvider); !ok {
55-
panic(fmt.Sprintf(
56-
"expected field 'Client.%s' of type '%s' to implement 'serviceProvider'",
57-
field.Name, field.Type.Name(),
58-
))
59-
}
60-
61-
serviceFieldNames = append(serviceFieldNames, field.Name)
62-
}
63-
}
21+
// Service types embedding service[T] will implement setup()
22+
// on their own to set up any service-specific configuration.

setup.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package payrex
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"strings"
7+
)
8+
9+
var serviceFieldNames []string = []string{}
10+
11+
// setupServices sets up the Service fields.
12+
func (c *Client) setupServices() {
13+
// I use reflection here mainly just for convenience: whenever new services
14+
// are added I can just add them as a field to Client and I don't have to do anything else.
15+
v := reflect.ValueOf(c).Elem()
16+
for _, fieldName := range serviceFieldNames {
17+
service := v.FieldByName(fieldName).Addr().Interface().(serviceProvider)
18+
19+
service.setupClient(c)
20+
service.setup()
21+
}
22+
}
23+
24+
// init checks that all Service fields in the [Client] struct implement [serviceProvider],
25+
// and saves the service field names in [serviceFieldNames] for later use.
26+
func init() {
27+
v := reflect.ValueOf(&Client{}).Elem()
28+
29+
for _, field := range reflect.VisibleFields(v.Type()) {
30+
if !field.IsExported() || !strings.HasPrefix(field.Type.Name(), "Service") {
31+
continue
32+
}
33+
34+
serviceField := v.FieldByName(field.Name).Addr().Interface()
35+
36+
if _, ok := serviceField.(serviceProvider); !ok {
37+
panic(fmt.Sprintf(
38+
"expected field 'Client.%s' of type '%s' to implement 'serviceProvider'",
39+
field.Name, field.Type.Name(),
40+
))
41+
}
42+
43+
serviceFieldNames = append(serviceFieldNames, field.Name)
44+
}
45+
}

0 commit comments

Comments
 (0)