option

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 16, 2024 License: MIT Imports: 1 Imported by: 5

README

option

Go Reference Go Report Card codecov gosec

This package aims to make it easy to use the options pattern in Go. It uses generics to ensure type safety, and has no dependencies outside the standard library.

Getting Started

Go Get
go get github.com/broothie/option
Import
import "github.com/broothie/option"

Usage

Let's say you have a Server that you'd like to be configurable:

package server

import (
	"database/sql"
	"log/slog"
)

type Server struct {
	logger *slog.Logger
	db     *sql.DB
}

First, provide callers with option builders:

func Logger(logger *slog.Logger) option.Func[*Server] {
	return func(server *Server) (*Server, error) {
		server.logger = logger
		return server, nil
	}
}

func DB(name string) option.Func[*Server] {
	return func(server *Server) (*Server, error) {
		db, err := sql.Open("pg", name)
		if err != nil {
			return nil, err
		}
		
		server.db = db
		return server, nil
	}
}

Then define a constructor that accepts a variadic argument of type option.Option[*Server]. In it, use option.Apply to run the new server instance through the provided options.

func New(options ...option.Option[*Server]) (*Server, error) {
    return option.Apply(new(Server), options...)
}

Now, callers can use the options pattern when instantiating your server:

srv, err := server.New(
	server.Logger(slog.New(slog.NewTextHandler(os.Stdout, nil))),
	server.DB("some-connection-string"),
)
Implementing Option

Let's say you want your server to always respond with a set of HTTP headers:

type Server struct {
	headers http.Header
}

You can create a custom Option for configuring this headers like this:

type Headers http.Header

func (h Headers) Apply(server *Server) (*Server, error) {
	server.headers = http.Header(h)
	return server, nil
}

Now, a caller can pass configure their server's headers like this:

srv, err := server.New(server.Headers{
	"Content-Type": {"application/json"},
	"X-From": {"my-app"}
})

Documentation

Overview

Package option provides a small, strongly typed set of tools for building with the options pattern.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Apply

func Apply[T any](t T, options ...Option[T]) (T, error)

Apply applies a list of options to t.

Types

type Func

type Func[T any] func(T) (T, error)

Func is a function that satisfies the Option interface.

func (Func[T]) Apply

func (f Func[T]) Apply(t T) (T, error)

Apply applies the Func to t.

type Option

type Option[T any] interface {
	Apply(T) (T, error)
}

Option provides an interface for options to satisfy. Concrete usages of Option are typically Funcs returned from a builder function.

type Options

type Options[T any] []Option[T]

Options is a list of Option, and satisfies the Option interface.

func NewOptions

func NewOptions[T any](options ...Option[T]) Options[T]

NewOptions converts a []Option to an Options.

func (Options[T]) Apply

func (o Options[T]) Apply(t T) (T, error)

Apply applies a list of options to t.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL