Skip to content

Commit

Permalink
refactor: replace props map with struct fields
Browse files Browse the repository at this point in the history
Use an int to store property existence and style struct fields to store
the actual values for each non-bool property.

Fixes: #139
Fixes: #141
  • Loading branch information
aymanbagabas committed Mar 28, 2024
1 parent f16ea2b commit 4df5e56
Show file tree
Hide file tree
Showing 5 changed files with 367 additions and 155 deletions.
102 changes: 71 additions & 31 deletions get.go
Expand Up @@ -416,74 +416,114 @@ func (s Style) GetTransform() func(string) string {

// Returns whether or not the given property is set.
func (s Style) isSet(k propKey) bool {
_, exists := s.rules[k]
return exists
return s.props.has(k)
}

func (s Style) getAsBool(k propKey, defaultVal bool) bool {
v, ok := s.rules[k]
if !ok {
if !s.isSet(k) {
return defaultVal
}
if b, ok := v.(bool); ok {
return b
}
return defaultVal
return s.isSet(k)
}

func (s Style) getAsColor(k propKey) TerminalColor {
v, ok := s.rules[k]
if !ok {
if !s.isSet(k) {
return noColor
}
if c, ok := v.(TerminalColor); ok {

var c TerminalColor
switch k {

Check failure on line 435 in get.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.widthKey, lipgloss.heightKey, lipgloss.alignHorizontalKey, lipgloss.alignVerticalKey, lipgloss.paddingTopKey, lipgloss.paddingRightKey, lipgloss.paddingBottomKey, lipgloss.paddingLeftKey, lipgloss.colorWhitespaceKey, lipgloss.marginTopKey, lipgloss.marginRightKey, lipgloss.marginBottomKey, lipgloss.marginLeftKey, lipgloss.borderStyleKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.inlineKey, lipgloss.maxWidthKey, lipgloss.maxHeightKey, lipgloss.tabWidthKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey, lipgloss.transformKey (exhaustive)

Check failure on line 435 in get.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.widthKey, lipgloss.heightKey, lipgloss.alignHorizontalKey, lipgloss.alignVerticalKey, lipgloss.paddingTopKey, lipgloss.paddingRightKey, lipgloss.paddingBottomKey, lipgloss.paddingLeftKey, lipgloss.colorWhitespaceKey, lipgloss.marginTopKey, lipgloss.marginRightKey, lipgloss.marginBottomKey, lipgloss.marginLeftKey, lipgloss.borderStyleKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.inlineKey, lipgloss.maxWidthKey, lipgloss.maxHeightKey, lipgloss.tabWidthKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey, lipgloss.transformKey (exhaustive)
case foregroundKey:
c = s.fgColor
case backgroundKey:
c = s.bgColor
case marginBackgroundKey:
c = s.marginBgColor
case borderTopForegroundKey:
c = s.borderTopFgColor
case borderRightForegroundKey:
c = s.borderRightFgColor
case borderBottomForegroundKey:
c = s.borderBottomFgColor
case borderLeftForegroundKey:
c = s.borderLeftFgColor
case borderTopBackgroundKey:
c = s.borderTopBgColor
case borderRightBackgroundKey:
c = s.borderRightBgColor
case borderBottomBackgroundKey:
c = s.borderBottomBgColor
case borderLeftBackgroundKey:
c = s.borderLeftBgColor
}

if c != nil {
return c
}

return noColor
}

func (s Style) getAsInt(k propKey) int {
v, ok := s.rules[k]
if !ok {
if !s.isSet(k) {
return 0
}
if i, ok := v.(int); ok {
return i
switch k {

Check failure on line 471 in get.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.foregroundKey, lipgloss.backgroundKey, lipgloss.alignHorizontalKey, lipgloss.alignVerticalKey, lipgloss.colorWhitespaceKey, lipgloss.marginBackgroundKey, lipgloss.borderStyleKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.borderTopForegroundKey, lipgloss.borderRightForegroundKey, lipgloss.borderBottomForegroundKey, lipgloss.borderLeftForegroundKey, lipgloss.borderTopBackgroundKey, lipgloss.borderRightBackgroundKey, lipgloss.borderBottomBackgroundKey, lipgloss.borderLeftBackgroundKey, lipgloss.inlineKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey, lipgloss.transformKey (exhaustive)

Check failure on line 471 in get.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.foregroundKey, lipgloss.backgroundKey, lipgloss.alignHorizontalKey, lipgloss.alignVerticalKey, lipgloss.colorWhitespaceKey, lipgloss.marginBackgroundKey, lipgloss.borderStyleKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.borderTopForegroundKey, lipgloss.borderRightForegroundKey, lipgloss.borderBottomForegroundKey, lipgloss.borderLeftForegroundKey, lipgloss.borderTopBackgroundKey, lipgloss.borderRightBackgroundKey, lipgloss.borderBottomBackgroundKey, lipgloss.borderLeftBackgroundKey, lipgloss.inlineKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey, lipgloss.transformKey (exhaustive)
case widthKey:
return s.width
case heightKey:
return s.height
case paddingTopKey:
return s.paddingTop
case paddingRightKey:
return s.paddingRight
case paddingBottomKey:
return s.paddingBottom
case paddingLeftKey:
return s.paddingLeft
case marginTopKey:
return s.marginTop
case marginRightKey:
return s.marginRight
case marginBottomKey:
return s.marginBottom
case marginLeftKey:
return s.marginLeft
case maxWidthKey:
return s.maxWidth
case maxHeightKey:
return s.maxHeight
case tabWidthKey:
return s.tabWidth
}
return 0
}

func (s Style) getAsPosition(k propKey) Position {
v, ok := s.rules[k]
if !ok {
if !s.isSet(k) {
return Position(0)
}
if p, ok := v.(Position); ok {
return p
switch k {

Check failure on line 506 in get.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.foregroundKey, lipgloss.backgroundKey, lipgloss.widthKey, lipgloss.heightKey, lipgloss.paddingTopKey, lipgloss.paddingRightKey, lipgloss.paddingBottomKey, lipgloss.paddingLeftKey, lipgloss.colorWhitespaceKey, lipgloss.marginTopKey, lipgloss.marginRightKey, lipgloss.marginBottomKey, lipgloss.marginLeftKey, lipgloss.marginBackgroundKey, lipgloss.borderStyleKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.borderTopForegroundKey, lipgloss.borderRightForegroundKey, lipgloss.borderBottomForegroundKey, lipgloss.borderLeftForegroundKey, lipgloss.borderTopBackgroundKey, lipgloss.borderRightBackgroundKey, lipgloss.borderBottomBackgroundKey, lipgloss.borderLeftBackgroundKey, lipgloss.inlineKey, lipgloss.maxWidthKey, lipgloss.maxHeightKey, lipgloss.tabWidthKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey, lipgloss.transformKey (exhaustive)

Check failure on line 506 in get.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.foregroundKey, lipgloss.backgroundKey, lipgloss.widthKey, lipgloss.heightKey, lipgloss.paddingTopKey, lipgloss.paddingRightKey, lipgloss.paddingBottomKey, lipgloss.paddingLeftKey, lipgloss.colorWhitespaceKey, lipgloss.marginTopKey, lipgloss.marginRightKey, lipgloss.marginBottomKey, lipgloss.marginLeftKey, lipgloss.marginBackgroundKey, lipgloss.borderStyleKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.borderTopForegroundKey, lipgloss.borderRightForegroundKey, lipgloss.borderBottomForegroundKey, lipgloss.borderLeftForegroundKey, lipgloss.borderTopBackgroundKey, lipgloss.borderRightBackgroundKey, lipgloss.borderBottomBackgroundKey, lipgloss.borderLeftBackgroundKey, lipgloss.inlineKey, lipgloss.maxWidthKey, lipgloss.maxHeightKey, lipgloss.tabWidthKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey, lipgloss.transformKey (exhaustive)
case alignHorizontalKey:
return s.alignHorizontal
case alignVerticalKey:
return s.alignVertical
}
return Position(0)
}

func (s Style) getBorderStyle() Border {
v, ok := s.rules[borderStyleKey]
if !ok {
if !s.isSet(borderStyleKey) {
return noBorder
}
if b, ok := v.(Border); ok {
return b
}
return noBorder
return s.borderStyle
}

func (s Style) getAsTransform(k propKey) func(string) string {

Check warning on line 522 in get.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'k' seems to be unused, consider removing or renaming it as _ (revive)
v, ok := s.rules[k]
if !ok {
if !s.isSet(transformKey) {
return nil
}
if fn, ok := v.(func(string) string); ok {
return fn
}
return nil
return s.transform
}

// Split a string into lines, additionally returning the size of the widest
Expand Down
162 changes: 141 additions & 21 deletions set.go
@@ -1,34 +1,154 @@
package lipgloss

// This could (should) probably just be moved into NewStyle(). We've broken it
// out, so we can call it in a lazy way.
func (s *Style) init() {
if s.rules == nil {
s.rules = make(rules)
}
}

// Set a value on the underlying rules map.
func (s *Style) set(key propKey, value interface{}) {
s.init()

switch v := value.(type) {
case int:
// We don't allow negative integers on any of our other values, so just keep
// them at zero or above. We could use uints instead, but the
// conversions are a little tedious, so we're sticking with ints for
// sake of usability.
set := true // whether or not to set or unset the prop
switch key {

Check failure on line 10 in set.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.colorWhitespaceKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.inlineKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey (exhaustive)

Check failure on line 10 in set.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.colorWhitespaceKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.inlineKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey (exhaustive)
case foregroundKey:
s.fgColor = colorOrNil(value)
case backgroundKey:
s.bgColor = colorOrNil(value)
case widthKey:
s.width = max(0, value.(int))
case heightKey:
s.height = max(0, value.(int))
case alignHorizontalKey:
s.alignHorizontal = value.(Position)
case alignVerticalKey:
s.alignVertical = value.(Position)
case paddingTopKey:
s.paddingTop = max(0, value.(int))
case paddingRightKey:
s.paddingRight = max(0, value.(int))
case paddingBottomKey:
s.paddingBottom = max(0, value.(int))
case paddingLeftKey:
s.paddingLeft = max(0, value.(int))
case marginTopKey:
s.marginTop = max(0, value.(int))
case marginRightKey:
s.marginRight = max(0, value.(int))
case marginBottomKey:
s.marginBottom = max(0, value.(int))
case marginLeftKey:
s.marginLeft = max(0, value.(int))
case marginBackgroundKey:
s.marginBgColor = colorOrNil(value)
case borderStyleKey:
s.borderStyle = value.(Border)
case borderTopForegroundKey:
s.borderTopFgColor = colorOrNil(value)
case borderRightForegroundKey:
s.borderRightFgColor = colorOrNil(value)
case borderBottomForegroundKey:
s.borderBottomFgColor = colorOrNil(value)
case borderLeftForegroundKey:
s.borderLeftFgColor = colorOrNil(value)
case borderTopBackgroundKey:
s.borderTopBgColor = colorOrNil(value)
case borderRightBackgroundKey:
s.borderRightBgColor = colorOrNil(value)
case borderBottomBackgroundKey:
s.borderBottomBgColor = colorOrNil(value)
case borderLeftBackgroundKey:
s.borderLeftBgColor = colorOrNil(value)
case maxWidthKey:
s.maxWidth = max(0, value.(int))
case maxHeightKey:
s.maxHeight = max(0, value.(int))
case tabWidthKey:
// TabWidth is the only property that may have a negative value (and
// that negative value can be no less than -1).
if key == tabWidthKey {
s.rules[key] = v
break
s.tabWidth = value.(int)
case transformKey:
s.transform = value.(func(string) string)
default:
if v, ok := value.(bool); ok {
set = v
}
}

// We don't allow negative integers on any of our other values, so just keep
// them at zero or above. We could use uints instead, but the
// conversions are a little tedious, so we're sticking with ints for
// sake of usability.
s.rules[key] = max(0, v)
// Set the prop on
if set {
s.props = s.props.set(key)
} else {
s.props = s.props.unset(key)
}
}

// setFrom sets the property from another style.
func (s *Style) setFrom(key propKey, i Style) {
switch key {

Check failure on line 85 in set.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.colorWhitespaceKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.inlineKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey (exhaustive)

Check failure on line 85 in set.go

View workflow job for this annotation

GitHub Actions / lint-soft

missing cases in switch of type lipgloss.propKey: lipgloss.boldKey, lipgloss.italicKey, lipgloss.underlineKey, lipgloss.strikethroughKey, lipgloss.reverseKey, lipgloss.blinkKey, lipgloss.faintKey, lipgloss.colorWhitespaceKey, lipgloss.borderTopKey, lipgloss.borderRightKey, lipgloss.borderBottomKey, lipgloss.borderLeftKey, lipgloss.inlineKey, lipgloss.underlineSpacesKey, lipgloss.strikethroughSpacesKey (exhaustive)
case foregroundKey:
s.set(foregroundKey, i.fgColor)
case backgroundKey:
s.set(backgroundKey, i.bgColor)
case widthKey:
s.set(widthKey, i.width)
case heightKey:
s.set(heightKey, i.height)
case alignHorizontalKey:
s.set(alignHorizontalKey, i.alignHorizontal)
case alignVerticalKey:
s.set(alignVerticalKey, i.alignVertical)
case paddingTopKey:
s.set(paddingTopKey, i.paddingTop)
case paddingRightKey:
s.set(paddingRightKey, i.paddingRight)
case paddingBottomKey:
s.set(paddingBottomKey, i.paddingBottom)
case paddingLeftKey:
s.set(paddingLeftKey, i.paddingLeft)
case marginTopKey:
s.set(marginTopKey, i.marginTop)
case marginRightKey:
s.set(marginRightKey, i.marginRight)
case marginBottomKey:
s.set(marginBottomKey, i.marginBottom)
case marginLeftKey:
s.set(marginLeftKey, i.marginLeft)
case marginBackgroundKey:
s.set(marginBackgroundKey, i.marginBgColor)
case borderStyleKey:
s.set(borderStyleKey, i.borderStyle)
case borderTopForegroundKey:
s.set(borderTopForegroundKey, i.borderTopFgColor)
case borderRightForegroundKey:
s.set(borderRightForegroundKey, i.borderRightFgColor)
case borderBottomForegroundKey:
s.set(borderBottomForegroundKey, i.borderBottomFgColor)
case borderLeftForegroundKey:
s.set(borderLeftForegroundKey, i.borderLeftFgColor)
case borderTopBackgroundKey:
s.set(borderTopBackgroundKey, i.borderTopBgColor)
case borderRightBackgroundKey:
s.set(borderRightBackgroundKey, i.borderRightBgColor)
case borderBottomBackgroundKey:
s.set(borderBottomBackgroundKey, i.borderBottomBgColor)
case borderLeftBackgroundKey:
s.set(borderLeftBackgroundKey, i.borderLeftBgColor)
case maxWidthKey:
s.set(maxWidthKey, i.maxWidth)
case maxHeightKey:
s.set(maxHeightKey, i.maxHeight)
case tabWidthKey:
s.set(tabWidthKey, i.tabWidth)
case transformKey:
s.set(transformKey, i.transform)
default:
s.rules[key] = v
s.set(key, i.isSet(key))
}
}

func colorOrNil(c interface{}) TerminalColor {
if c, ok := c.(TerminalColor); ok {
return c
}
return nil
}

// Bold sets a bold formatting rule.
Expand Down

0 comments on commit 4df5e56

Please sign in to comment.