summaryrefslogtreecommitdiffstats
path: root/dependencies/pkg/mod/github.com/vbauerster/mpb/v6@v6.0.4/bar_filler_spinner.go
blob: 0817b19ec4662bb026b63975c9108b5278979efc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package mpb

import (
	"io"
	"strings"

	"github.com/mattn/go-runewidth"
	"github.com/vbauerster/mpb/v6/decor"
	"github.com/vbauerster/mpb/v6/internal"
)

// SpinnerAlignment enum.
type SpinnerAlignment int

// SpinnerAlignment kinds.
const (
	SpinnerOnLeft SpinnerAlignment = iota
	SpinnerOnMiddle
	SpinnerOnRight
)

// SpinnerDefaultStyle is a style for rendering a spinner.
var SpinnerDefaultStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}

type spinnerFiller struct {
	frames    []string
	count     uint
	alignment SpinnerAlignment
}

// NewSpinnerFiller returns a BarFiller implementation which renders
// a spinner. If style is nil or zero length, SpinnerDefaultStyle is
// applied. To be used with `*Progress.Add(...) *Bar` method.
func NewSpinnerFiller(style []string, alignment SpinnerAlignment) BarFiller {
	if len(style) == 0 {
		style = SpinnerDefaultStyle
	}
	filler := &spinnerFiller{
		frames:    style,
		alignment: alignment,
	}
	return filler
}

func (s *spinnerFiller) Fill(w io.Writer, reqWidth int, stat decor.Statistics) {
	width := internal.CheckRequestedWidth(reqWidth, stat.AvailableWidth)

	frame := s.frames[s.count%uint(len(s.frames))]
	frameWidth := runewidth.StringWidth(frame)

	if width < frameWidth {
		return
	}

	switch rest := width - frameWidth; s.alignment {
	case SpinnerOnLeft:
		io.WriteString(w, frame+strings.Repeat(" ", rest))
	case SpinnerOnMiddle:
		str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2)
		io.WriteString(w, str)
	case SpinnerOnRight:
		io.WriteString(w, strings.Repeat(" ", rest)+frame)
	}
	s.count++
}