Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: replace props map with struct fields #6

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
104 changes: 72 additions & 32 deletions get.go
Original file line number Diff line number Diff line change
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.attrs&int(k) != 0
}

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 {
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 {
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 {
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 {
v, ok := s.rules[k]
if !ok {
func (s Style) getAsTransform(propKey) func(string) string {
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
169 changes: 148 additions & 21 deletions set.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,161 @@
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.
switch key {
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 {
if v {
s.attrs |= int(key)
} else {
s.attrs &^= int(key)
}
} else if attrs, ok := value.(int); ok {
// bool attrs
if attrs&int(key) != 0 {
s.attrs |= int(key)
} else {
s.attrs &^= int(key)
}
}
}

// 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
s.props = s.props.set(key)
}

// setFrom sets the property from another style.
func (s *Style) setFrom(key propKey, i Style) {
switch key {
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
// Set attributes for set bool properties
s.set(key, i.attrs)
}
}

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

// Bold sets a bold formatting rule.
Expand Down