Skip to content

Commit

Permalink
Add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
fortuna committed Oct 29, 2024
1 parent 92eca9d commit f194150
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 30 deletions.
54 changes: 29 additions & 25 deletions x/configurl/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,36 @@ import (
"strings"
)

// Config is a pre-parsed generic config created from pipe-separated URLs.
type Config struct {
URL url.URL
BaseConfig *Config
}

// Provider creates an instance from a config.
type Provider[ObjectType any] interface {
NewInstance(ctx context.Context, config *Config) (ObjectType, error)
}

// BuildFunc is a convenience type for functions that create a instances of ObjectType given a [Config].
type BuildFunc[ObjectType any] func(ctx context.Context, config *Config) (ObjectType, error)

// TypeRegistry registers config types.
type TypeRegistry[ObjectType any] interface {
RegisterType(subtype string, newInstance BuildFunc[ObjectType]) error
}

// ExtensibleProvider is [Provider] implementation that can be extended via its [TypeRegistry] interface.
type ExtensibleProvider[ObjectType comparable] struct {
// Instance to return when config is nil.
BaseInstance ObjectType
builders map[string]BuildFunc[ObjectType]
}

type BuildFunc[ObjectType any] func(ctx context.Context, config *Config) (ObjectType, error)
var (
_ Provider[any] = (*ExtensibleProvider[any])(nil)
_ TypeRegistry[any] = (*ExtensibleProvider[any])(nil)
)

func (p *ExtensibleProvider[ObjectType]) buildersMap() map[string]BuildFunc[ObjectType] {
if p.builders == nil {
Expand All @@ -37,16 +61,16 @@ func (p *ExtensibleProvider[ObjectType]) buildersMap() map[string]BuildFunc[Obje
}

// RegisterType will register a factory for the given subtype.
func (p *ExtensibleProvider[ObjectType]) RegisterType(subtype string, newDialer BuildFunc[ObjectType]) error {
func (p *ExtensibleProvider[ObjectType]) RegisterType(subtype string, newInstance BuildFunc[ObjectType]) error {
builders := p.buildersMap()
if _, found := builders[subtype]; found {
return fmt.Errorf("type %v registered twice", subtype)
}
builders[subtype] = newDialer
builders[subtype] = newInstance
return nil
}

// NewInstance creates a new instance according to the config.
// NewInstance creates a new instance of ObjectType according to the config.
func (p *ExtensibleProvider[ObjectType]) NewInstance(ctx context.Context, config *Config) (ObjectType, error) {
var zero ObjectType
if config == nil {
Expand All @@ -63,27 +87,7 @@ func (p *ExtensibleProvider[ObjectType]) NewInstance(ctx context.Context, config
return newDialer(ctx, config)
}

var (
_ Provider[any] = (*ExtensibleProvider[any])(nil)
_ TypeRegistry[any] = (*ExtensibleProvider[any])(nil)
)

// Provider creates an instance from a config.
type Provider[ObjectType any] interface {
NewInstance(ctx context.Context, config *Config) (ObjectType, error)
}

// TypeRegistry registers config types.
type TypeRegistry[ObjectType any] interface {
RegisterType(subtype string, newInstance BuildFunc[ObjectType]) error
}

// Transport config.
type Config struct {
URL url.URL
BaseConfig *Config
}

// ParseConfig will parse a config given as a string and return the structured [Config].
func ParseConfig(configText string) (*Config, error) {
parts := strings.Split(strings.TrimSpace(configText), "|")
if len(parts) == 1 && parts[0] == "" {
Expand Down
14 changes: 9 additions & 5 deletions x/configurl/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,17 @@ Defining custom strategies - You can define your custom strategy by implementing
// or
p := NewDefaultConfigModule()
// Register your custom dialer.
p.StreamDialers.RegisterType("custom", newStreamDialerWithCustom)
p.PacketDialers.RegisterType("custom", newPacketDialerWithCustom)
// then use it
p.StreamDialers.RegisterType("custom", func(ctx context.Context, config *Config) (transport.StreamDialer, error) {
// Build logic
// ...
})
p.PacketDialers.RegisterType("custom", func(ctx context.Context, config *Config) (transport.PacketDialer, error) {
// Build logic
// ...
})
// Then use it
dialer, err := p.NewStreamDialer(context.Background(), "custom://config")
where newStreamDialerWithCustom and newPacketDialerWithCustom implement [BuildFunc[transport.StreamDialer]] and [BuildFunc[transport.PacketDialer]].
[Onion Routing]: https://en.wikipedia.org/wiki/Onion_routing
*/
package configurl

0 comments on commit f194150

Please sign in to comment.