mirror of
https://github.com/tmrts/go-patterns.git
synced 2025-02-18 05:23:14 +03:00
Options is an implementation detail and adds no value by being exported. By unexporting Options we decrease the API surface and maintain the ability to make changes without breaking user expectations.
1.5 KiB
1.5 KiB
Functional Options
Functional options are a method of implementing clean/eloquent APIs in Go. Options implemented as a function set the state of that option.
Implementation
Options
package file
type options struct {
UID int
GID int
Flags int
Contents string
Permissions os.FileMode
}
type Option func(*options)
func UID(userID int) Option {
return func(args *options) {
args.UID = userID
}
}
func GID(groupID int) Option {
return func(args *options) {
args.GID = groupID
}
}
func Contents(c string) Option {
return func(args *options) {
args.Contents = c
}
}
func Permissions(perms os.FileMode) Option {
return func(args *options) {
args.Permissions = perms
}
}
Constructor
package file
func New(filepath string, setters ...Option) error {
// Default options
args := &options{
UID: os.Getuid(),
GID: os.Getgid(),
Contents: "",
Permissions: 0666,
Flags: os.O_CREATE | os.O_EXCL | os.O_WRONLY,
}
for _, setter := range setters {
setter(args)
}
f, err := os.OpenFile(filepath, args.Flags, args.Permissions)
if err != nil {
return err
} else {
defer f.Close()
}
if _, err := f.WriteString(args.Contents); err != nil {
return err
}
return f.Chown(args.UID, args.GID)
}
Usage
emptyFile, err := file.New("/tmp/empty.txt")
if err != nil {
panic(err)
}
fillerFile, err := file.New("/tmp/file.txt", file.UID(1000), file.Contents("Lorem Ipsum Dolor Amet"))
if err != nil {
panic(err)
}