Codebase list golang-github-vbauerster-mpb / 0e30992
on complete wrapper Vladimir Bauer 6 years ago
10 changed file(s) with 91 addition(s) and 166 deletion(s). Raw diff Collapse all Expand all
4646 for _, widthConf := range wcc {
4747 wc = widthConf
4848 }
49 wc.Init()
5049 if pairFmt == "" {
5150 pairFmt = "%d / %d"
5251 }
5352 d := &countersDecorator{
54 WC: wc,
53 WC: wc.Init(),
5554 unit: unit,
5655 pairFmt: pairFmt,
5756 }
6059
6160 type countersDecorator struct {
6261 WC
63 unit int
64 pairFmt string
65 completeMsg *string
62 unit int
63 pairFmt string
6664 }
6765
6866 func (d *countersDecorator) Decor(st *Statistics) string {
69 if st.Completed && d.completeMsg != nil {
70 return d.FormatMsg(*d.completeMsg)
71 }
72
7367 var res string
7468 switch d.unit {
7569 case UnitKiB:
8276
8377 return d.FormatMsg(res)
8478 }
85
86 func (d *countersDecorator) OnCompleteMessage(msg string) {
87 d.completeMsg = &msg
88 }
5151 }
5252
5353 // Decorator interface.
54 // A decorator must implement this interface, in order to be used with
55 // mpb library.
54 // Implementors should embed WC type, that way only single method
55 // Decor(*Statistics) needs to be implemented, the rest will be handled
56 // by WC type.
5657 type Decorator interface {
57 ConfigSetter
58 Configurator
5859 Synchronizer
5960 Decor(*Statistics) string
6061 }
6667 Sync() (chan int, bool)
6768 }
6869
69 // ConfigSetter interface.
70 type ConfigSetter interface {
71 SetConfig(config WC) (old WC)
72 }
73
74 // OnCompleteMessenger interface.
75 // Decorators implementing this interface suppose to return provided
76 // string on complete event.
77 type OnCompleteMessenger interface {
78 OnCompleteMessage(string)
70 // Configurator interface.
71 type Configurator interface {
72 GetConf() WC
73 SetConf(*WC)
7974 }
8075
8176 // AmountReceiver interface.
82 // EWMA based decorators must implement this one.
77 // EWMA based decorators need to implement this one.
8378 type AmountReceiver interface {
8479 NextAmount(int64, ...time.Duration)
8580 }
135130 }
136131
137132 // Init initializes width related config.
138 func (wc *WC) Init() {
133 func (wc *WC) Init() WC {
139134 wc.dynFormat = "%%"
140135 if (wc.C & DidentRight) != 0 {
141136 wc.dynFormat += "-"
143138 wc.dynFormat += "%ds"
144139 wc.staticFormat = fmt.Sprintf(wc.dynFormat, wc.W)
145140 if (wc.C & DSyncWidth) != 0 {
141 // it's deliberate choice to override wsync on each Init() call,
142 // this way globals like WCSyncSpace can be reused
146143 wc.wsync = make(chan int)
147144 }
145 return *wc
148146 }
149147
150148 // Sync is implementation of Synchronizer interface.
152150 return wc.wsync, (wc.C & DSyncWidth) != 0
153151 }
154152
155 // SetConfig sets new conf and returns old one.
156 func (wc *WC) SetConfig(conf WC) (old WC) {
157 conf.Init()
158 old = *wc
159 *wc = conf
160 return old
153 // GetConf is implementation of Configurator interface.
154 func (wc *WC) GetConf() WC {
155 return *wc
161156 }
162157
163 // OnComplete returns decorator, which wraps provided decorator, with
164 // sole purpose to display provided message on complete event.
165 //
166 // `decorator` Decorator to wrap
167 //
168 // `message` message to display on complete event
169 func OnComplete(decorator Decorator, message string) Decorator {
170 if d, ok := decorator.(OnCompleteMessenger); ok {
171 d.OnCompleteMessage(message)
172 }
173 return decorator
158 // SetConf is implementation of Configurator interface.
159 func (wc *WC) SetConf(conf *WC) {
160 *wc = conf.Init()
174161 }
2424 for _, widthConf := range wcc {
2525 wc = widthConf
2626 }
27 wc.Init()
2827 d := &elapsedDecorator{
29 WC: wc,
28 WC: wc.Init(),
3029 startTime: startTime,
3130 producer: chooseTimeProducer(style),
3231 }
3534
3635 type elapsedDecorator struct {
3736 WC
38 startTime time.Time
39 producer func(time.Duration) string
40 msg string
41 completeMsg *string
37 startTime time.Time
38 producer func(time.Duration) string
39 msg string
4240 }
4341
4442 func (d *elapsedDecorator) Decor(st *Statistics) string {
45 if st.Completed {
46 if d.completeMsg != nil {
47 return d.FormatMsg(*d.completeMsg)
48 }
49 return d.FormatMsg(d.msg)
43 if !st.Completed {
44 d.msg = d.producer(time.Since(d.startTime))
5045 }
51
52 d.msg = d.producer(time.Since(d.startTime))
5346 return d.FormatMsg(d.msg)
5447 }
55
56 func (d *elapsedDecorator) OnCompleteMessage(msg string) {
57 d.completeMsg = &msg
58 }
4949 for _, widthConf := range wcc {
5050 wc = widthConf
5151 }
52 wc.Init()
5352 d := &movingAverageETA{
54 WC: wc,
53 WC: wc.Init(),
5554 average: average,
5655 normalizer: normalizer,
5756 producer: chooseTimeProducer(style),
6160
6261 type movingAverageETA struct {
6362 WC
64 average ewma.MovingAverage
65 normalizer TimeNormalizer
66 producer func(time.Duration) string
67 completeMsg *string
63 average ewma.MovingAverage
64 normalizer TimeNormalizer
65 producer func(time.Duration) string
6866 }
6967
7068 func (d *movingAverageETA) Decor(st *Statistics) string {
71 if st.Completed && d.completeMsg != nil {
72 return d.FormatMsg(*d.completeMsg)
73 }
74
7569 v := math.Round(d.average.Value())
7670 remaining := time.Duration((st.Total - st.Current) * int64(v))
7771 if d.normalizer != nil {
9084 return
9185 }
9286 d.average.Add(durPerItem)
93 }
94
95 func (d *movingAverageETA) OnCompleteMessage(msg string) {
96 d.completeMsg = &msg
9787 }
9888
9989 // AverageETA decorator. It's wrapper of NewAverageETA.
119109 for _, widthConf := range wcc {
120110 wc = widthConf
121111 }
122 wc.Init()
123112 d := &averageETA{
124 WC: wc,
113 WC: wc.Init(),
125114 startTime: startTime,
126115 normalizer: normalizer,
127116 producer: chooseTimeProducer(style),
131120
132121 type averageETA struct {
133122 WC
134 startTime time.Time
135 normalizer TimeNormalizer
136 producer func(time.Duration) string
137 completeMsg *string
123 startTime time.Time
124 normalizer TimeNormalizer
125 producer func(time.Duration) string
138126 }
139127
140128 func (d *averageETA) Decor(st *Statistics) string {
141 if st.Completed && d.completeMsg != nil {
142 return d.FormatMsg(*d.completeMsg)
143 }
144
145129 var remaining time.Duration
146130 if st.Current != 0 {
147131 durPerItem := float64(time.Since(d.startTime)) / float64(st.Current)
152136 }
153137 }
154138 return d.FormatMsg(d.producer(remaining))
155 }
156
157 func (d *averageETA) OnCompleteMessage(msg string) {
158 d.completeMsg = &msg
159139 }
160140
161141 func (d *averageETA) AverageAdjust(startTime time.Time) {
1919 }
2020 md := &mergeDecorator{
2121 Decorator: decorator,
22 wc: decorator.GetConf(),
2223 placeHolders: make([]*placeHolderDecorator, len(placeholders)),
2324 }
24 md.wc = decorator.SetConfig(md.wc)
25 decorator.SetConf(&WC{})
2526 for i, wc := range placeholders {
26 wc.Init()
2727 md.placeHolders[i] = &placeHolderDecorator{
28 WC: wc,
28 WC: wc.Init(),
2929 wsync: make(chan int),
3030 }
3131 }
99 for _, widthConf := range wcc {
1010 wc = widthConf
1111 }
12 wc.Init()
1312 d := &nameDecorator{
14 WC: wc,
13 WC: wc.Init(),
1514 msg: name,
1615 }
1716 return d
1918
2019 type nameDecorator struct {
2120 WC
22 msg string
23 complete *string
21 msg string
2422 }
2523
2624 func (d *nameDecorator) Decor(st *Statistics) string {
27 if st.Completed && d.complete != nil {
28 return d.FormatMsg(*d.complete)
29 }
3025 return d.FormatMsg(d.msg)
3126 }
32
33 func (d *nameDecorator) OnCompleteMessage(msg string) {
34 d.complete = &msg
35 }
0 package decor
1
2 // OnComplete returns decorator, which wraps provided decorator, with
3 // sole purpose to display provided message on complete event.
4 //
5 // `decorator` Decorator to wrap
6 //
7 // `message` message to display on complete event
8 func OnComplete(decorator Decorator, message string) Decorator {
9 d := &onCompleteWrapper{
10 Decorator: decorator,
11 wc: decorator.GetConf(),
12 msg: message,
13 }
14 return d
15 }
16
17 type onCompleteWrapper struct {
18 Decorator
19 wc WC
20 msg string
21 }
22
23 func (d *onCompleteWrapper) Decor(st *Statistics) string {
24 if st.Completed {
25 return d.wc.FormatMsg(d.msg)
26 }
27 return d.Decorator.Decor(st)
28 }
5050 for _, widthConf := range wcc {
5151 wc = widthConf
5252 }
53 wc.Init()
5453 if fmt == "" {
5554 fmt = "% d"
5655 }
5756 d := &percentageDecorator{
58 WC: wc,
57 WC: wc.Init(),
5958 fmt: fmt,
6059 }
6160 return d
6362
6463 type percentageDecorator struct {
6564 WC
66 fmt string
67 completeMsg *string
65 fmt string
6866 }
6967
7068 func (d *percentageDecorator) Decor(st *Statistics) string {
71 if st.Completed && d.completeMsg != nil {
72 return d.FormatMsg(*d.completeMsg)
73 }
7469 p := internal.Percentage(st.Total, st.Current, 100)
7570 return d.FormatMsg(fmt.Sprintf(d.fmt, percentageType(p)))
7671 }
77
78 func (d *percentageDecorator) OnCompleteMessage(msg string) {
79 d.completeMsg = &msg
80 }
5858 if format == "" {
5959 format = "%.0f"
6060 }
61 wc.Init()
6261 d := &movingAverageSpeed{
63 WC: wc,
62 WC: wc.Init(),
6463 average: average,
6564 producer: chooseSpeedProducer(unit, format),
6665 }
6968
7069 type movingAverageSpeed struct {
7170 WC
72 producer func(float64) string
73 average ewma.MovingAverage
74 msg string
75 completeMsg *string
71 producer func(float64) string
72 average ewma.MovingAverage
73 msg string
7674 }
7775
7876 func (d *movingAverageSpeed) Decor(st *Statistics) string {
79 if st.Completed {
80 if d.completeMsg != nil {
81 return d.FormatMsg(*d.completeMsg)
77 if !st.Completed {
78 var speed float64
79 if v := math.Round(d.average.Value()); v != 0 {
80 speed = 1 / time.Duration(v).Seconds()
8281 }
83 return d.FormatMsg(d.msg)
82 d.msg = d.producer(speed)
8483 }
85
86 var speed float64
87 if v := math.Round(d.average.Value()); v != 0 {
88 speed = 1 / time.Duration(v).Seconds()
89 }
90
91 d.msg = d.producer(speed)
9284 return d.FormatMsg(d.msg)
9385 }
9486
10294 return
10395 }
10496 d.average.Add(durPerByte)
105 }
106
107 func (d *movingAverageSpeed) OnCompleteMessage(msg string) {
108 d.completeMsg = &msg
10997 }
11098
11199 // AverageSpeed decorator with dynamic unit measure adjustment. It's
140128 if format == "" {
141129 format = "%.0f"
142130 }
143 wc.Init()
144131 d := &averageSpeed{
145 WC: wc,
132 WC: wc.Init(),
146133 startTime: startTime,
147134 producer: chooseSpeedProducer(unit, format),
148135 }
151138
152139 type averageSpeed struct {
153140 WC
154 startTime time.Time
155 producer func(float64) string
156 msg string
157 completeMsg *string
141 startTime time.Time
142 producer func(float64) string
143 msg string
158144 }
159145
160146 func (d *averageSpeed) Decor(st *Statistics) string {
161 if st.Completed {
162 if d.completeMsg != nil {
163 return d.FormatMsg(*d.completeMsg)
164 }
165 return d.FormatMsg(d.msg)
147 if !st.Completed {
148 speed := float64(st.Current) / time.Since(d.startTime).Seconds()
149 d.msg = d.producer(speed)
166150 }
167151
168 speed := float64(st.Current) / time.Since(d.startTime).Seconds()
169 d.msg = d.producer(speed)
170
171152 return d.FormatMsg(d.msg)
172 }
173
174 func (d *averageSpeed) OnCompleteMessage(msg string) {
175 d.completeMsg = &msg
176153 }
177154
178155 func (d *averageSpeed) AverageAdjust(startTime time.Time) {
1111 for _, widthConf := range wcc {
1212 wc = widthConf
1313 }
14 wc.Init()
1514 if len(frames) == 0 {
1615 frames = defaultSpinnerStyle
1716 }
1817 d := &spinnerDecorator{
19 WC: wc,
18 WC: wc.Init(),
2019 frames: frames,
2120 }
2221 return d
2423
2524 type spinnerDecorator struct {
2625 WC
27 frames []string
28 count uint
29 complete *string
26 frames []string
27 count uint
3028 }
3129
3230 func (d *spinnerDecorator) Decor(st *Statistics) string {
33 if st.Completed && d.complete != nil {
34 return d.FormatMsg(*d.complete)
35 }
3631 frame := d.frames[d.count%uint(len(d.frames))]
3732 d.count++
3833 return d.FormatMsg(frame)
3934 }
40
41 func (d *spinnerDecorator) OnCompleteMessage(msg string) {
42 d.complete = &msg
43 }