11package payrex
22
3- import (
4- "fmt"
5- "reflect"
6- "strings"
7- )
8-
93// serviceProvider is the interface that all Service types implement.
104type 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.
0 commit comments