diff options
Diffstat (limited to 'bar_option.go')
-rw-r--r-- | bar_option.go | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/bar_option.go b/bar_option.go new file mode 100644 index 0000000..d3cb3e2 --- /dev/null +++ b/bar_option.go @@ -0,0 +1,200 @@ +package mpb + +import ( + "bytes" + "io" + + "github.com/vbauerster/mpb/v8/decor" +) + +// BarOption is a func option to alter default behavior of a bar. +type BarOption func(*bState) + +func inspect(decorators []decor.Decorator) (dest []decor.Decorator) { + for _, decorator := range decorators { + if decorator == nil { + continue + } + dest = append(dest, decorator) + } + return +} + +// AppendDecorators let you inject decorators to the bar's right side. +func AppendDecorators(decorators ...decor.Decorator) BarOption { + decorators = inspect(decorators) + return func(s *bState) { + s.aDecorators = decorators + } +} + +// PrependDecorators let you inject decorators to the bar's left side. +func PrependDecorators(decorators ...decor.Decorator) BarOption { + decorators = inspect(decorators) + return func(s *bState) { + s.pDecorators = decorators + } +} + +// BarID sets bar id. +func BarID(id int) BarOption { + return func(s *bState) { + s.id = id + } +} + +// BarWidth sets bar width independent of the container. +func BarWidth(width int) BarOption { + return func(s *bState) { + s.reqWidth = width + } +} + +// BarQueueAfter puts this (being constructed) bar into the queue. +// BarPriority will be inherited from the argument bar. +// When argument bar completes or aborts queued bar replaces its place. +func BarQueueAfter(bar *Bar) BarOption { + return func(s *bState) { + s.waitBar = bar + } +} + +// BarRemoveOnComplete removes both bar's filler and its decorators +// on complete event. +func BarRemoveOnComplete() BarOption { + return func(s *bState) { + s.rmOnComplete = true + } +} + +// BarFillerClearOnComplete clears bar's filler on complete event. +// It's shortcut for BarFillerOnComplete(""). +func BarFillerClearOnComplete() BarOption { + return BarFillerOnComplete("") +} + +// BarFillerOnComplete replaces bar's filler with message, on complete event. +func BarFillerOnComplete(message string) BarOption { + return BarFillerMiddleware(func(base BarFiller) BarFiller { + return BarFillerFunc(func(w io.Writer, st decor.Statistics) error { + if st.Completed { + _, err := io.WriteString(w, message) + return err + } + return base.Fill(w, st) + }) + }) +} + +// BarFillerMiddleware provides a way to augment the underlying BarFiller. +func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption { + if middle == nil { + return nil + } + return func(s *bState) { + s.filler = middle(s.filler) + } +} + +// BarPriority sets bar's priority. Zero is highest priority, i.e. bar +// will be on top. This option isn't effective with `BarQueueAfter` option. +func BarPriority(priority int) BarOption { + return func(s *bState) { + s.priority = priority + } +} + +// BarExtender extends bar with arbitrary lines. Provided BarFiller will be +// called at each render/flush cycle. Any lines written to the underlying +// io.Writer will extend the bar either in above (rev = true) or below +// (rev = false) direction. +func BarExtender(filler BarFiller, rev bool) BarOption { + if filler == nil { + return nil + } + fn := makeExtenderFunc(filler, rev) + return func(s *bState) { + s.extender = fn + } +} + +func makeExtenderFunc(filler BarFiller, rev bool) extenderFunc { + buf := new(bytes.Buffer) + base := func(rows []io.Reader, stat decor.Statistics) ([]io.Reader, error) { + err := filler.Fill(buf, stat) + if err != nil { + buf.Reset() + return rows, err + } + for { + b, err := buf.ReadBytes('\n') + if err != nil { + break + } + rows = append(rows, bytes.NewReader(b)) + } + buf.Reset() + return rows, err + } + + if !rev { + return base + } + return func(rows []io.Reader, stat decor.Statistics) ([]io.Reader, error) { + rows, err := base(rows, stat) + if err != nil { + return rows, err + } + for left, right := 0, len(rows)-1; left < right; left, right = left+1, right-1 { + rows[left], rows[right] = rows[right], rows[left] + } + return rows, err + } +} + +// BarFillerTrim removes leading and trailing space around the underlying BarFiller. +func BarFillerTrim() BarOption { + return func(s *bState) { + s.trimSpace = true + } +} + +// BarNoPop disables bar pop out of container. Effective when +// PopCompletedMode of container is enabled. +func BarNoPop() BarOption { + return func(s *bState) { + s.noPop = true + } +} + +// BarOptional will return provided option only when cond is true. +func BarOptional(option BarOption, cond bool) BarOption { + if cond { + return option + } + return nil +} + +// BarOptOn will return provided option only when predicate evaluates to true. +func BarOptOn(option BarOption, predicate func() bool) BarOption { + if predicate() { + return option + } + return nil +} + +// BarFuncOptional will call option and return its value only when cond is true. +func BarFuncOptional(option func() BarOption, cond bool) BarOption { + if cond { + return option() + } + return nil +} + +// BarFuncOptOn will call option and return its value only when predicate evaluates to true. +func BarFuncOptOn(option func() BarOption, predicate func() bool) BarOption { + if predicate() { + return option() + } + return nil +} |