bar filler: dynamic flush func based on rev
Vladimir Bauer
2 years ago
| 51 | 51 | type bFiller struct { |
| 52 | 52 | components [components]component |
| 53 | 53 | meta [components]func(io.Writer, ...interface{}) error |
| 54 | rev bool | |
| 54 | flush func(w io.Writer, sections ...flushSection) error | |
| 55 | 55 | tipOnComplete bool |
| 56 | 56 | tip struct { |
| 57 | 57 | frames []component |
| 155 | 155 | func (s *barStyle) Build() BarFiller { |
| 156 | 156 | bf := &bFiller{ |
| 157 | 157 | meta: s.metaFuncs, |
| 158 | rev: s.rev, | |
| 159 | 158 | tipOnComplete: s.tipOnComplete, |
| 160 | 159 | } |
| 161 | 160 | bf.components[iLbound] = component{ |
| 183 | 182 | bf.tip.frames[i] = component{ |
| 184 | 183 | width: runewidth.StringWidth(t), |
| 185 | 184 | bytes: []byte(t), |
| 185 | } | |
| 186 | } | |
| 187 | if s.rev { | |
| 188 | bf.flush = func(w io.Writer, sections ...flushSection) error { | |
| 189 | for i := len(sections) - 1; i >= 0; i-- { | |
| 190 | if s := sections[i]; len(s.bytes) != 0 { | |
| 191 | err := s.meta(w, s.bytes) | |
| 192 | if err != nil { | |
| 193 | return err | |
| 194 | } | |
| 195 | } | |
| 196 | } | |
| 197 | return nil | |
| 198 | } | |
| 199 | } else { | |
| 200 | bf.flush = func(w io.Writer, sections ...flushSection) error { | |
| 201 | for _, s := range sections { | |
| 202 | if len(s.bytes) != 0 { | |
| 203 | err := s.meta(w, s.bytes) | |
| 204 | if err != nil { | |
| 205 | return err | |
| 206 | } | |
| 207 | } | |
| 208 | } | |
| 209 | return nil | |
| 186 | 210 | } |
| 187 | 211 | } |
| 188 | 212 | return bf |
| 240 | 264 | padding = append(padding, "…"...) |
| 241 | 265 | } |
| 242 | 266 | |
| 243 | err = flush(w, s.rev, | |
| 267 | err = s.flush(w, | |
| 244 | 268 | flushSection{s.meta[iRefiller], refilling}, |
| 245 | 269 | flushSection{s.meta[iFiller], filling}, |
| 246 | 270 | flushSection{s.meta[iTip], tip.bytes}, |
| 252 | 276 | return s.meta[iRbound](w, s.components[iRbound].bytes) |
| 253 | 277 | } |
| 254 | 278 | |
| 255 | func flush(w io.Writer, rev bool, sections ...flushSection) error { | |
| 256 | if rev { | |
| 257 | for i := len(sections) - 1; i >= 0; i-- { | |
| 258 | if s := sections[i]; len(s.bytes) != 0 { | |
| 259 | err := s.meta(w, s.bytes) | |
| 260 | if err != nil { | |
| 261 | return err | |
| 262 | } | |
| 263 | } | |
| 264 | } | |
| 265 | } else { | |
| 266 | for _, s := range sections { | |
| 267 | if len(s.bytes) != 0 { | |
| 268 | err := s.meta(w, s.bytes) | |
| 269 | if err != nil { | |
| 270 | return err | |
| 271 | } | |
| 272 | } | |
| 273 | } | |
| 274 | } | |
| 275 | return nil | |
| 276 | } | |
| 277 | ||
| 278 | 279 | func makeMetaFunc(fn func(...interface{}) string) func(io.Writer, ...interface{}) error { |
| 279 | 280 | return func(w io.Writer, a ...interface{}) (err error) { |
| 280 | 281 | for i := 0; i < len(a) && err == nil; i++ { |