/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/flexibletable/cells.go
160 строк
4 KB
Joshua Blum
prevent message id from being truncated (#24179)
20 май 2020, 18:53
Не верифицирован
20 май 2020, 18:53
e589f55
Код
Авторство
О чём код?
// Copyright 2016 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package flexibletable import ( "math" "strconv" "strings" ) // Alignment defines how the content of a cell should align type Alignment int // Possible Alignment values const ( Left Alignment = iota // default Right Center ) // Cell defines a cell (column) in a row type Cell struct { // Content is the content of the cell. It can be either a SingleCell or a // MultiCell Content cellContent // Alignment specifies how the content of a cell should align Alignment Alignment // Frame defines a "frame" around the content. The array defines two strings, // which are added before and after the content, before any paddings are // inserted. Frame [2]string } func (c Cell) full() string { return c.Content.full() } func (c Cell) render(widthConstraint int) (string, error) { frameWidth := len(c.Frame[0]) + len(c.Frame[1]) minWidth := c.Content.minWidth() + frameWidth if minWidth > widthConstraint { return "", WidthTooSmallError{} } return c.Frame[0] + c.Content.render(widthConstraint-frameWidth) + c.Frame[1], nil } func (c Cell) renderWithPadding(width int) (string, error) { str, err := c.render(width) if err != nil { return "", err } return c.addPadding(str, width) } func (c Cell) addPadding(str string, width int) (string, error) { padding := width - len(str) if padding == 0 { return str, nil } switch c.Alignment { case Left: return str + strings.Repeat(" ", padding), nil case Right: return strings.Repeat(" ", padding) + str, nil case Center: return strings.Repeat(" ", padding/2) + str + strings.Repeat(" ", padding-padding/2), nil default: return "", BadOptionError{optionName: "Alignment"} } } type cellContent interface { render(maxWidth int) string minWidth() int full() string } // emptyCell is an implementation of cellContent that is only used internally // in flexibletable package during rendering. type emptyCell struct{} func (emptyCell) render(int) string { return "" } func (emptyCell) minWidth() int { return 0 } func (emptyCell) full() string { return "" } // SingleCell defines cell content with a single string. If being truncated, // the truncated part is replaced with "..." type SingleCell struct { // Item is, well, the content. Item string } func (c SingleCell) full() string { return c.Item } func (c SingleCell) render(maxWidth int) string { if len(c.Item) <= maxWidth { return c.Item } return c.Item[:maxWidth-3] + "..." } func (c SingleCell) minWidth() int { if len(c.Item) < 3 { return len(c.Item) } return 3 // "..." } // MultiCell defines cell content with multiple strings. If being truncated, it // looks like this: "item1,item2,+4..." type MultiCell struct { // Sep is the separator between different items Sep string // Items are the content Items []string } func (c MultiCell) full() string { return strings.Join(c.Items, c.Sep) } func (c MultiCell) render(maxWidth int) (ret string) { retIfFull := "+" + strconv.Itoa(len(c.Items)) + "..." for i, item := range c.Items { var plus string if len(ret) > 0 { plus = c.Sep + item } else { plus = item } if len(plus)+len(ret) <= maxWidth { ret += plus } else { return retIfFull } newRetIfFull := ret + c.Sep + "+" + strconv.Itoa(len(c.Items)-i-1) + "..." if len(newRetIfFull) <= maxWidth { retIfFull = newRetIfFull } } return ret } func (c MultiCell) minWidth() int { simpleLen := len(strings.Join(c.Items, c.Sep)) digestMin := int(math.Ceil(math.Log10(float64(len(c.Items)+1)))) + 4 // "+9..." if simpleLen < digestMin { return simpleLen } return digestMin }