Files
learngo/27-functional-programming/log-parser-exp/report.go
2019-08-06 01:42:59 +03:00

85 lines
1.4 KiB
Go

package main
import "io"
type (
retrieveFunc func(io.Reader) ([]result, error)
filterFunc func(result) bool
groupFunc func(result) string
writeFunc func(io.Writer, []result) error
)
type report struct {
input io.Reader
output io.Writer
retrieve retrieveFunc
filter filterFunc
group groupFunc
write writeFunc
}
func newReport() *report {
return &report{
filter: noopFilter,
}
}
func (r *report) from(reader io.Reader) *report {
r.input = reader
return r
}
func (r *report) to(writer io.Writer) *report {
r.output = writer
return r
}
func (r *report) retrieveFrom(fn retrieveFunc) *report {
r.retrieve = fn
return r
}
func (r *report) filterBy(fn filterFunc) *report {
r.filter = fn
return r
}
func (r *report) groupBy(fn groupFunc) *report {
r.group = fn
return r
}
func (r *report) writeTo(fn writeFunc) *report {
r.write = fn
return r
}
func (r *report) run() ([]result, error) {
if r.retrieve == nil {
panic("report retrieve cannot be nil")
}
results, err := r.retrieve(r.input)
if err != nil {
return nil, err
}
// noop if filter is nil
results = filterBy(results, r.filter)
// group func is more tricky
// you don't want to create an unnecessary map
if r.group != nil {
results = groupBy(results, r.group)
}
// TODO: prefer: noop writer
if r.write != nil {
if err := r.write(r.output, results); err != nil {
return nil, err
}
}
return results, nil
}