Decorator interface: signature change
This is necessary to support meta wrappers
Vladimir Bauer
2 years ago
| 3 | 3 | "fmt" |
| 4 | 4 | "time" |
| 5 | 5 | |
| 6 | "github.com/acarl005/stripansi" | |
| 7 | 6 | "github.com/mattn/go-runewidth" |
| 8 | 7 | ) |
| 9 | 8 | |
| 65 | 64 | // `DecorFunc` into a `Decorator` interface by using provided |
| 66 | 65 | // `func Any(DecorFunc, ...WC) Decorator`. |
| 67 | 66 | type Decorator interface { |
| 68 | Configurator | |
| 69 | 67 | Synchronizer |
| 70 | Decor(Statistics) string | |
| 68 | Formatter | |
| 69 | Decor(Statistics) (str string, viewWidth int) | |
| 71 | 70 | } |
| 72 | 71 | |
| 73 | 72 | // DecorFunc func type. |
| 81 | 80 | Sync() (chan int, bool) |
| 82 | 81 | } |
| 83 | 82 | |
| 84 | // Configurator interface. | |
| 85 | type Configurator interface { | |
| 86 | GetConf() WC | |
| 87 | SetConf(WC) | |
| 83 | // Formatter interface. | |
| 84 | // Format method needs to be called from within Decorator.Decor method | |
| 85 | // in order to format string according to decor.WC settings. | |
| 86 | // No need to implement manually as long as decor.WC is embedded. | |
| 87 | type Formatter interface { | |
| 88 | Format(string) (str string, viewWidth int) | |
| 88 | 89 | } |
| 89 | 90 | |
| 90 | 91 | // Wrapper interface. |
| 134 | 135 | wsync chan int |
| 135 | 136 | } |
| 136 | 137 | |
| 137 | // FormatMsg formats final message according to WC.W and WC.C. | |
| 138 | // Should be called by any Decorator implementation. | |
| 139 | func (wc WC) FormatMsg(msg string) string { | |
| 140 | pureWidth := runewidth.StringWidth(msg) | |
| 141 | viewWidth := runewidth.StringWidth(stripansi.Strip(msg)) | |
| 142 | max := wc.W | |
| 138 | // Format should be called by any Decorator implementation. | |
| 139 | // Returns formatted string and its view (visual) width. | |
| 140 | func (wc WC) Format(str string) (string, int) { | |
| 141 | viewWidth := runewidth.StringWidth(str) | |
| 142 | if wc.W > viewWidth { | |
| 143 | viewWidth = wc.W | |
| 144 | } | |
| 143 | 145 | if (wc.C & DSyncWidth) != 0 { |
| 144 | viewWidth := viewWidth | |
| 145 | 146 | if (wc.C & DextraSpace) != 0 { |
| 146 | 147 | viewWidth++ |
| 147 | 148 | } |
| 148 | 149 | wc.wsync <- viewWidth |
| 149 | max = <-wc.wsync | |
| 150 | viewWidth = <-wc.wsync | |
| 150 | 151 | } |
| 151 | return wc.fill(msg, max-viewWidth+pureWidth) | |
| 152 | return wc.fill(str, viewWidth), viewWidth | |
| 152 | 153 | } |
| 153 | 154 | |
| 154 | 155 | // Init initializes width related config. |
| 174 | 175 | return wc.wsync, (wc.C & DSyncWidth) != 0 |
| 175 | 176 | } |
| 176 | 177 | |
| 177 | // GetConf is implementation of Configurator interface. | |
| 178 | func (wc *WC) GetConf() WC { | |
| 179 | return *wc | |
| 180 | } | |
| 181 | ||
| 182 | // SetConf is implementation of Configurator interface. | |
| 183 | func (wc *WC) SetConf(conf WC) { | |
| 184 | *wc = conf.Init() | |
| 185 | } | |
| 186 | ||
| 187 | 178 | func initWC(wcc ...WC) WC { |
| 188 | 179 | var wc WC |
| 189 | 180 | for _, nwc := range wcc { |